class MainClass
{
struct Vector
{
public double x, y, z;
public Vector(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
public Vector(Vector rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
}
public override string ToString()
{
return "(" + x + "," + y + "," + z + ")";
}
public static Vector operator +(Vector lhs, Vector rhs)
{
Vector result = new Vector(lhs);
result.x += rhs.x;
result.y += rhs.y;
result.z += rhs.z;
return result;
}
}
static void Main()
{
Vector vect1, vect2, vect3;
vect1 = new Vector(3.0, 3.0, 1.0);
vect2 = new Vector(2.0, -4.0, -4.0);
vect3 = vect1 + vect2;
Console.WriteLine("vect1=" + vect1.ToString());
Console.WriteLine("vect2=" + vect2.ToString());
Console.WriteLine("vect3=" + vect3.ToString());
}
}
上例定义了一个在数学中常见的矢量相加的+号重载
注意:
1.虽然+=一般用作运算符,但实际上其操作分为两个部分:相加和赋值。C#不允许重载=运算符,但如果重载+运算符,编译器就会自动使用+运算符的重载来执行+=运算符的操作。-=、&=、/=赋值运算符也遵循此规则。
2.比较运算符的重载
C#中有6个比较运算符,它们分为3对:==、!=;<、>;<=、>=
C#要求成对重载比较运算符,如果重载了==,也必须重载!=,否则就会产生编辑错误,另外,比较运算符必须返回bool类型的值。这是它们与算术运算符的根本区别。两个数相加或相减的结果,理论上取决数的类型,而两个Vector的相乘会得到一个标量,另一个例子是.NET基类System.DateTime,两个DateTime实例相减,得到的结果不是DateTime,而是一个System.TimeSpan实例,但比较运算得到的如果不是bool类型的值,就没有任何意义
3.并不是所有的运算符都可以重载。可以重载的运算符如下表所示
类别 | 运算符 | 限制 |
算术二元运算符 | +,*,/,-,% | 无 |
算术一元运算符 | +,-,++,-- | 无 |
算术二元运算符 | &,|,^,<<,>> | 无 |
算术一元运算符 | !,~,true,false | true和false运算符必须成对重载 |
比较运算符 | ==,!=,>=,<,<=,> | 必须成对重载 |
赋值运算符 | +=,-=,*=,/=,>>=,<<=,%=,&=,|=,^= | 不能显示重载这些运算符,在重写单个运算符如+,-,*等时,它们会被隐式重写 |
索引运算符 | [] | 不能直接重载索引运算符。索引运算符成员类型允许在类和结构上支持索引运算符 |
数据类型转换运算符 | () | 不能直接重载数据类型运算符。用户定义的数据类型转换允许定义定制的数据类型转化 |