【发布时间】:2019-12-09 18:35:15
【问题描述】:
我有这门课:
public class Transform<PositionType, RotationType, ScaleType>
where PositionType : Position
where RotationType : Rotation
where ScaleType : Scale
{
public Transform<PositionType, RotationType, ScaleType> Parent;
public PositionType GlobalPosition;
// The next line has a compile error: Cannot implicitly convert type 'Position'
// to 'PositionType'. An explicit conversion exists (are you missing a cast?)
public PositionType LocalPosition => Parent.GlobalPosition - GlobalPosition;
public RotationType GlobalRotation;
// The next line has a compile error: Cannot implicitly convert type 'Rotation'
// to 'RotationType'. An explicit conversion exists (are you missing a cast?)
public RotationType LocalRotation => Parent.GlobalRotation - GlobalRotation;
public ScaleType GlobalScale;
// The next line has a compile error: Cannot implicitly convert type 'Scale'
// to 'ScaleType'. An explicit conversion exists (are you missing a cast?)
public ScaleType LocalScale => Parent.GlobalScale - GlobalScale;
}
Position:(Scale和Rotation定义相同)
public class Position
{
public Position(int axis)
{
Axis = new float[axis];
}
public Position(float[] axis)
{
Axis = axis;
}
public static Position operator -(Position a, Position b)
{
if (a.Axis.Length != b.Axis.Length)
{
throw new System.Exception("The axis of the two Positions are not comparable.");
}
Position difference = new Position(a.Axis);
for (int i = 0; i < difference.Axis.Length; i++)
{
difference.Axis[i] = a.Axis[i] - b.Axis[i];
}
return difference;
}
public float[] Axis;
}
对我来说这看起来完全有效,所以我很困惑为什么它会产生编译时错误。 在保留此功能的同时,我应该如何解决此问题?
【问题讨论】:
-
错误信息非常具体,告诉你该怎么做。哪部分不明白?
-
顺便说一句,这些类型参数名称更习惯用法为
TPosition、TRotation、TScale。 -
我的猜测是您的线性代数运算符(例如
Parent.Rotation - Rotation)不受限制生成与传入类型相同的通用子类型。 IE。Parent.Rotation - Rotation不能保证是RotationType类型,即使Parent.Rotation和Rotation是;它只是保证是Rotation类型。需要查看minimal reproducible example 才能确定。 -
Scale、Position和Rotation的定义是什么? -
是的,所以
Position operator -(Position a, Position b)只能保证生成Position而不是它的子类PositionType,即使a和b是子类型PositionType。而且实际上没有办法在c#中直接创建这样一个通用运算符+,参见C# Generic Operators。