Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#继承类型转换错误_C#_Oop_Inheritance_Casting - Fatal编程技术网

C#继承类型转换错误

C#继承类型转换错误,c#,oop,inheritance,casting,C#,Oop,Inheritance,Casting,我对C#中的继承有点陌生。我有两个类Velocity.cs和Position.cs,它们继承自基类Vector.cs。我试图在Vector.cs内部创建一个名为subtract()的方法,该方法可以从Velocity.cs和Position.cs访问 这是减法的代码 public Vector subtract(Vector v) { double nx = this.x - v.x; double ny = this.y - v.y;

我对C#中的继承有点陌生。我有两个类
Velocity.cs
Position.cs
,它们继承自基类
Vector.cs
。我试图在
Vector.cs
内部创建一个名为
subtract()
的方法,该方法可以从
Velocity.cs
Position.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);
    }

}
}

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

        Velocity v1 = new Velocity(5);
        Velocity v2 = new Velocity(7);
        Velocity result = v1.subtract(v2);
我得到一个错误,说不能显式地在“速度”和“向量”之间转换你忘记了一个强制转换吗

所以我尝试了
Velocity result=(Velocity)v1.减法(v2)但是,这会导致以下错误:发生“System.InvalidCastException”类型的未处理异常

如何重写此函数以使其正常工作?我真的必须用返回类型
Vector
Velocity
Position
制作三个版本的函数吗?如果是的话,继承的意义是什么?我可以把它们放在相关的类中


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

< P>你不需要编码三个版本。 您可以编写泛型函数

public T Substract<T> (T vector) where T: Vector
{
    ...
    return new T(...); // Edited to demonstrate last line as asked from comment
}
public T Substract(T vector),其中T:vector
{
...
返回新的T(…);//编辑以演示注释中要求的最后一行
}

请注意您的代码

Velocity result = (Velocity)v1.subtract(v2);
不将减法的结果强制转换为速度类型。正确的方法是:

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

我认为
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>
{
}
…您将能够实现您的目标:

Velocity result = v1.Subtract(v2);

啊,我知道这里发生了什么。所以减法函数返回一个向量对象,但C#无法将向量解析回速度。我以前在复制构造函数使用它之前就遇到过这个问题

在向量类中:

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 result = new Velocity((v1).subtract(v2));

这是有道理的,但最后一行看起来如何<代码>返回新的T(mag、ang)这是一个非常好的答案。@MatíasFidemraizer我仍然在做错事。。这也不对
返回t,其中t:Vector,new(mag,ang)我不喜欢这个解决方案。为什么要对
速度执行减法,并且需要提供结果类型作为通用参数?这似乎很奇怪。@ryanmattscott
new()
约束是定义
T
必须提供一个公共的无参数构造函数。对其他类型的构造函数没有约束..请注意,不要执行
new Random()…,new Random()。相反,创建Random类的静态实例并使用它。另外,减法方法返回一个
向量。您正试图将其分配给
Velocity
类型的变量。虽然
速度
确实是
向量
,但
向量
不一定是
速度
(它可以是
位置
)。你总是可以做
Vector result=v1.减法(v2)
但您只能访问
Vector
中定义的公共字段,这取决于您的用例,可能还不够。另一个旁注:根据C#命名约定,方法名称应该以大写字母开头,即
Change(…)
Subtract(…)
。我知道您喜欢第一个回答者的方法。顺便说一句,双重检查我的。。。我相信它以一种更直接的方式符合你的需求。这将是完全相同的事情,不能解决他/她的问题。此评论是不正确的。某种形式的
(T)v.s(u)
已经被视为
(T)(v.s(u))
,而不是你想象中的
((T)v.s(u)
。因此,额外的括号很好,但不是必需的,因此您的注释是错误的
在我看来很难看。@JeppeStigNielsen给我一个替代方案,我将改进代码片段:D@JeppeStigNielsen另一种方法是使用隐式接口实现来设置一些属性,而不公开它们……我不太明白。什么接口具有什么属性(或方法)?显式接口实现在某种意义上是
public
(如果接口类型是public;
internal
,如果接口是public)。@JeppeStigNielsen您知道显式实现就像实现它们的类中的私有成员一样。。。当然,您可以将该实现强制转换为接口类型以访问其成员。
public class Velocity : Vector
{
    public Velocity(Vector vector)
        : base(vector)
    {
    }
}
Velocity result = new Velocity((v1).subtract(v2));