运算符重载问题

发布于 11-25 10:56 字数 864 浏览 3 评论 0原文

假设我有一个类:

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

为什么会出现这种情况?

Suppose I have a class:

 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);
   }
 }

Have a derived class:

 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)
    {

    }
 }

No if I execute folowing code:

 Vector v1 = new MyVector(10);    //type MyVector

 Vector v2 = new MyVector(20);    //type MyVector

 Vector v3 = v1 + v2;             //executed operator is of Vector class

Here is executed Vector's + operator, but the type of v1 and v2 is MyVector, so v3 is Vector type at this point.

Why this happens?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

万水千山粽是情ミ2024-12-02 10:56:05

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

v1v2 必须输入 MyVector,编译器才能选择 MyVector 类中定义的重载。

(可选)在 Vector 类上定义一个方法 public virtual Vector Add(Vector other) 并让 MyVector 重写它。然后从 Vectoroperator+ 方法调用此方法,这将按您的预期工作。 (MyVector 将不需要定义 operator+ 本身。)

Because the type of the variables v1 and v2 are Vector, not MyVector. Operator overloads are static methods that are resolved by the compiler at compile-time, not at runtime; they cannot be overridden.

v1 and v2 will have to be typed MyVector for the compiler to select the overload defined in the MyVector class.

Optionally, define a method public virtual Vector Add(Vector other) on the Vector class and have MyVector override it. Then call this method from the operator+ method of Vector and this will work as you expected. (MyVector would then not need to define operator+ itself.)

自控2024-12-02 10:56:05

就像 cdhowie 回答 一样,方法解析是在编译类型完成的。

但如果您使用 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 的 true 类型,而不是编译时感知的类型(如 foo() 中)。

:-)

PS:在运行时延迟类型解析可能会更慢,而且不太安全(因为应该在编译时捕获的错误将在执行期间被发现)。

Like cdhowie answered, the method resolution is done at compile type.

But if you're working with C# 4.0, you can try the following.

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
}

To see that in the bar() method, the method call resolution will be done at runtime, using the true type of v1 and v2, instead of the perceived type at compile time (as in foo()).

:-)

P.S.: Delaying type resolution at runtime can be slower, and less safe (as errors that should have been caught at compile time will be discovered during execution).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文