C#继承类型转换错误

时间:2017-02-05 15:20:08

标签: c# oop inheritance casting

我对C#中的继承有点新意。我有两个继承自基类Velocity.cs的类Position.csVector.cs。我尝试在subtract()内创建一个名为Vector.cs的方法,该方法可以从Velocity.csPosition.cs访问。

这是减法的代码。

     public Vector subtract(Vector v) {
        double nx = this.x - v.x;
        double ny = this.y - v.y;
        double mag = Math.Sqrt(x * x + y * y);
        double ang = Math.Atan2(y, x);
        return new Vector(mag, ang);
    }

定义Velocity.cs类的代码如下。

class Velocity : Vector{

    public Velocity(Position p1, Position p2, double vpref) : base(p1, p2) {
        normalize();
        scale(vpref);
    }

    public Velocity(double vmax) : base(new Random().NextDouble()*vmax, new Random().NextDouble()*2*Math.PI) {

    }

    public void change(Velocity v) {
        x = v.x;
        y = v.y;
        magnitude = Math.Sqrt(x * x + y * y);
        angle = Math.Atan2(y, x);
    }

}

}

当我尝试调用函数减去外部时,如下所示:

        Velocity v1 = new Velocity(5);
        Velocity v2 = new Velocity(7);
        Velocity result = v1.subtract(v2);

我收到错误消息无法明确转换' Velocity'和' Vector'你忘记演员了?

所以我尝试Velocity result = (Velocity)v1.subtract(v2);会导致以下错误:未处理的类型' System.InvalidCastException'发生

如何重写此功能才能使其正常工作?我是否真的必须使用返回类型Vector VelocityPosition制作三个版本的函数?如果是这样,继承点是什么?我可以把它们放在相关的课堂上。

注意:我知道速度等级有点小,当时可能看起来毫无意义,我稍后会添加更多,我在中间一个项目。

4 个答案:

答案 0 :(得分:2)

我相信Vector类应该接受泛型类型参数,让它知道派生类的类型:

public class Vector<TImpl> where TImpl : Vector
{
     public TImpl Subtract(TImpl v) 
     {
        double nx = this.x - v.x;
        double ny = this.y - v.y;
        double mag = Math.Sqrt(x * x + y * y);
        double ang = Math.Atan2(y, x);

        return (TImpl)Activator.CreateInstance(typeof(TImpl), new object[] { mag, ang });
    }
}

public class Velocity : Vector<Velocity>
{
}
顺便说一句,我觉得Subtract方法应该是一个扩展方法,一切看起来都不那么奇怪了:

public static class VectorExtensions
{
      public static TImpl Subtract<TImpl>(this TImpl vectorImpl, TImpl other)
             where TImpl : Vector
      {
        double nx = this.x - v.x;
        double ny = this.y - v.y;
        double mag = Math.Sqrt(x * x + y * y);
        double ang = Math.Atan2(y, x);

        return (TImpl)Activator.CreateInstance(typeof(TImpl), new object[] { mag, ang });
      }
}

......你将能够实现目标:

Velocity result = v1.Subtract(v2);

答案 1 :(得分:1)

啊,我看到这里发生了什么。因此,您的减法函数返回一个Vector对象,但C#无法将Vector解析回Velocity。过去之前我已经通过复制构造器来解决这个问题了。

所以在你的Vector类中:

public class Vector
{
    /// <summary>
    /// Copy Constructor
    /// </summary>
    /// <param name="toCopy">
    /// The vector object to copy
    /// </param>
    public Vector(Vector toCopy)
    {
        if (toCopy == null)
        {
            throw new ArgumentNullException("toCopy");
        }

        x = toCopy.x;
        y = toCopy.y;
        //What ever other properties you have, assign them here
    }
}

然后在你的Velocity课程中:

public class Velocity : Vector
{
    public Velocity(Vector vector)
        : base(vector)
    {
    }
}

最后,如何使用它:

Velocity result = new Velocity((v1).subtract(v2));

答案 2 :(得分:-1)

请注意您的代码

class GUI():
    ...
    def start(self):
        self.root.mainloop()

...
hi = GUI()
hi.start()

不会将减法方法的结果转换为Velocity类型。正确的方法是:

Velocity result = (Velocity)v1.subtract(v2);

答案 3 :(得分:-2)

你不需要编写三个版本的代码。 您可以编写通用函数。

public T Substract<T> (T vector) where T: Vector
{
    ...
    return new T(...); // Edited to demonstrate last line as asked from comment
}