我正在尝试创建2D矢量,其坐标是通用的(Vector2Dint,Vector2Dfloat等...),以便能够更轻松地进行一些数学运算。我已经看到这个问题非常接近我的问题:Can't operator == be applied to generic types in C#?但我的情况是“*”运算符。基本上我需要为这个向量做一些数学函数,比如“cross”或“dot”,这个例子就是这个:
public static T cross<T>(Vec2<T> u, Vec2<T> v)
{
return u.x * v.y - u.y * v.x;
}
Visual Studio告诉我的是:“运算符'*'不能应用于'T'和'T'类型的操作数”(T是坐标的类型)。我的想法是重载“Vec2”类中的'*'运算符,以便能够乘以这些坐标,具有:
public static Vec2<T> operator *(T x, T y)
{
return x * y;
}
但Visual Studio再次告诉我同样的事情。我确信我没有以正确的方式超载运营商,但我不知道原因。谢谢你的帮助
编辑1:好的,我们可以从中学到的是,如果你想为不同类型(int,float,double等等)定义一个函数,你想要性能,最好的方法是为每种类型定义函数,但现在,另一个问题出现了。如果你有一个很长的功能或几个长功能,¿这仍然是最好的方式吗?
答案 0 :(得分:0)
目前无法告诉编译器可以在泛型类型参数上使用哪些运算符。 github in the C# compiler repository在题为有趣但需要CLR支持的段落中讨论了以多种方式扩展通用约束的问题。
您还可以投票赞助此功能添加到Visual Studio Uservoice
答案 1 :(得分:0)
您收到此错误,因为类型&#34; T&#34;不明。如你所知,它可以是一个字符串,或任何类或结构。
这样做的一种方法是为所有&#34;预期&#34;提供过载。向量的类型
public static int cross(Vec2<int> u, Vec2<int> v)
{
return u.x * v.y - u.y * v.x;
}
public static double cross(Vec2<double> u, Vec2<double> v)
{
return u.x * v.y - u.y * v.x;
}
public static long cross(Vec2<long> u, Vec2<long> v)
{
return u.x * v.y - u.y * v.x;
}
public static float cross(Vec2<float> u, Vec2<float> v)
{
return u.x * v.y - u.y * v.x;
}
...
答案 2 :(得分:0)
嗯,这是一个非常难看的方式,我永远不会用它来进行游戏(速度),但它完全符合你的要求:
你的Vec2课程:
public class Vec2<T>
{
public T x;
public T y;
public static Vec2<T> operator *(Vec2<T> u, Vec2<T> v)
{
return u.Cross(v);
}
}
一个扩展类:
public static class Exts
{
public static T Cross<T>(this Vec2<T> u, Vec2<T> v)
{
if (u.x is double)
return (T)Convert.ChangeType(Convert.ToDouble(u.x) * Convert.ToDouble(v.y) - Convert.ToDouble(u.y) * Convert.ToDouble(v.x), typeof(T));
else if (u.y is float)
return (T)Convert.ChangeType(Convert.ToSingle(u.x) * Convert.ToSingle(v.y) - Convert.ToSingle(u.y) * Convert.ToSingle(v.x), typeof(T));
else if (u.x is decimal)
return (T)Convert.ChangeType(Convert.ToDecimal(u.x) * Convert.ToDecimal(v.y) - Convert.ToDecimal(u.y) * Convert.ToDecimal(v.x), typeof(T));
else
return (T)Convert.ChangeType(Convert.ToInt32(u.x) * Convert.ToInt32(v.y) - Convert.ToInt32(u.y) * Convert.ToInt32(v.x), typeof(T));
}
}