运算符重载问题

时间:2011-07-20 20:22:20

标签: c# operators

假设我有一个班级:

 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类型。

为什么会这样?

2 个答案:

答案 0 :(得分:3)

因为变量v1v2的类型是Vector,而不是MyVector。运算符重载是静态方法,由编译器在编译时解析,而不是在运行时;他们不能被推翻。

v1v2必须输入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()方法中看到,方法调用解析将在运行时使用真实类型v1v2完成,而不是在编译时感知类型(如foo())。

: - )

P.S。:在运行时延迟类型解析可能更慢,安全性更低(因为在执行期间将发现应该在编译时捕获的错误)。