假设我有一个班级:
public class Vector
{
public float X { get; set; }
public Vector(float xvalue)
{
X = xvalue;
}
public static Vector operator +(Vector v1, Vector v2)
{
return new Vector(v1.X + v2.X);
}
}
有派生类:
public class MyVector : Vector
{
public static MyVector operator +(MyVector v1, MyVector v2)
{
return new MyVector(v1.X + v2.X);
}
public MyVector(float xvalue):base(xvalue)
{
}
}
否,如果我执行以下代码:
Vector v1 = new MyVector(10); //type MyVector
Vector v2 = new MyVector(20); //type MyVector
Vector v3 = v1 + v2; //executed operator is of Vector class
这是执行Vector的+运算符,但v1和v2的类型是MyVector
,所以此时v3是Vector类型。
为什么会这样?
答案 0 :(得分:3)
因为变量v1
和v2
的类型是Vector
,而不是MyVector
。运算符重载是静态方法,由编译器在编译时解析,而不是在运行时;他们不能被推翻。
v1
和v2
必须输入MyVector
,编译器才能选择MyVector
类中定义的重载。
(可选)在public virtual Vector Add(Vector other)
类上定义方法Vector
并让MyVector
覆盖它。然后从operator+
的{{1}}方法调用此方法,这将按预期工作。 (Vector
则不需要自己定义MyVector
。)
答案 1 :(得分:1)
与cdhowie answered类似,方法解析以编译类型完成。
但是如果你正在使用C#4.0,你可以尝试以下方法。
void foo()
{
Vector v1 = new MyVector(10); // type MyVector
Vector v2 = new MyVector(20); // type MyVector
Vector v3 = v1 + v2; // Vector.operator + called
bar(v1, v2);
}
void bar(Vector p_v1, Vector p_v2)
{
dynamic v1 = p_v1; // dynamic type
dynamic v2 = p_v2; // dynamic type
Vector v3 = v1 + v2; // MyVector.operator + called
}
要在bar()
方法中看到,方法调用解析将在运行时使用真实类型v1
和v2
完成,而不是在编译时感知类型(如foo()
)。
: - )
P.S。:在运行时延迟类型解析可能更慢,安全性更低(因为在执行期间将发现应该在编译时捕获的错误)。