C#继承类型转换错误
我对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;
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)代码>我不喜欢这个解决方案。为什么要对速度执行减法,并且需要提供结果类型作为通用参数?这似乎很奇怪。@ryanmattscottnew()
约束是定义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));