1 操作符重载的一般原则:
- 重载的方法实现会用到operator关键字
- 重载的方法必须是public static
- 如果重载了 ==,那必须重载 != ,同时需要改写 Equals,GetHashCode,C#要求Equals与==的逻辑保持一致,这种同步关系本身是默认的,如果修改了Equals的比较,比如改成按内容比较,那么最好重载 ==,!=操作符,反之亦然,最好是在操作符重载中调用Equals方法
- 针对引用类型,==的逻辑跟Equals是一样的,默认的引用类型的比较是比较引用本身,改写了Equals方法,
- 此外操作符重载还涉及到不同类型的转换,public static implicit/explicit NewType operator =(OldType)
- 另外,在重载操作符 == 的时候,还需要注意,针对当前类型的变量的比较逻辑中,不能出现 ==,因为当前本身就是在针对 == 进行重载,如此调用必然递归调用,而出现StackOverflow的异常,解决的办法很简单,就是调用静态方法 ReferenceEquals
- Struct类型的变量比较,直接调用Equals就可以按照内容进行比较,但是 两个自定义值类型不能直接使用 == 的形式进行比较,如果需要的话,需要重写 operator
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StructCompareOnArrayAndTuple
{
struct ValDataSet
{
public Int32 ID;
public Int32 Age;
public String Name;
public static bool operator ==(ValDataSet v1, ValDataSet v2)
{
return v1.Equals(v2);
}
public static bool operator !=(ValDataSet v1, ValDataSet v2)
{
return !v1.Equals(v2);
}
}
class ValueTypeComparer : IRainyTester
{
public string TestComment
{
get;
private set;
}
public void Test()
{
TestComment = "Test Value type compare";
var vds = new ValDataSet { ID = 10, Age = 20, Name = "jack" };
var vds1 = new ValDataSet { ID = 10, Age = 20, Name = "jack" };
//if (vds.Equals(vds1))
//after operator override
if (vds == vds1)
{
TestResult = "Same Value Struct";
}
else
{
TestResult = "Diff Value Struct";
}
}
public string TestResult
{
get;
private set;
}
}
}
总结一点的是:
自定义Struct类型,直接调用Equals方法就是按值进行比较,但是默认不能调用 == 进行比较
自定义Class类型,直接调用 == 比较的是引用,需要按值进行比较,需要改写Equals,GetHashCode,最好重载 操作符 ==, !=