介绍
C# 允许用户定义的类型通过使用 operator
关键字定义静态成员函数来重载运算符。注意必须用 public
修饰且必须是类的静态的方法。但并非所有内置运算符都可以被重载,详见下表:
运算符 | 可重载性 |
+、-、!、~、++、--、true、false | 可以重载这些一元运算符, true和false运算符必须成对重载 |
+、-、*、/、%、&、|、^、<<、>> | 可以重载这些二元运算符 |
==、!=、<、>、<=、>= | 可以重载比较运算符,必须成对重载 |
&&、|| | 不能重载条件逻辑运算符,但可以使用能够重载的&和|进行计算 |
[] | 不能重载数组索引运算符,但可以定义索引器 |
() | 不能重载转换运算符,但可以定义新的转换运算符(请参见 explicit 和 implicit) |
+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>= | 不能显式重载赋值运算符,在重写单个运算符如+、-、%时,它们会被 隐式重写 |
=、.、?:、->、new、is、sizeof、typeof | 不能重载这些运算符 |
示例
internal class Program
{
public static void Main(string[] args)
{
var p1 = new Person();
p1.Id = 1;
p1.Name = "张三";
var p2 = p1;
var p3 = new Person();
p3.Id = 1;
p3.Name = "张三";
Console.WriteLine(object.ReferenceEquals(p1,p2)); // true
// <1>
Console.WriteLine(object.ReferenceEquals(p1,p3)); // false
Console.WriteLine(p1 == p2); // true
// <2>
Console.WriteLine(p1 == p3); // true
}
class Person
{
// == 与 != 必须成对重载
public static bool operator ==(Person left, Person right)
{
return left.Id == right.Id && left.Name == right.Name;
}
public static bool operator !=(Person left, Person right)
{
return left.Id != right.Id || left.Name != right.Name;
}
private int id;
private string name;
public int Id
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
}
}
可以看到 <1>
处的结果为 false
,说明 p1
和 p3
引用的不是同一个对象。而 <2>
处的执行结果为 true
,说明此时通过 ==
比较是执行了我们重载的运算符方法。
更多可参考微软官方文档。
相关面试题
在 C# 中, obj1 == obj2
的比较结果是否与 obj1.Equals(obj2)
相同?
答案:不一定,因为 ==
比较实际上是执行默认的运算符方法,除非 obj1
和 obj2
所属类型的 ==
运算符方法和 Equals
方法的比较规则相同它们的结果才相同。
评论区