繁体   English   中英

通用类型运算符

[英]Generic types operators

我正在尝试创建通用的2D向量(Vector2Dint,Vector2Dfloat等),以便能够更轻松地进行一些数学运算。 我已经看到这个问题与我的问题非常接近: 运算符==不能应用于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等)定义函数,并且想要性能,最好的方法就是定义函数对于每种类型,但是现在,我遇到了另一个问题。 如果您有一个很长的函数或几个长的函数,这仍然是最好的方法吗?

当前不可能告诉编译器可以在泛型类型参数上使用哪些运算符。 在C#编译器存储库中的github上的标题为“ 有趣但需要CLR支持 ”的段落中讨论了以多种方式扩展泛型约束的问题。

您也可以对要在Visual Studio Uservoice上添加的功能进行投票

您会收到此错误,因为类型“ T”是未知的。 就您所知,它可以是字符串,也可以是任何种类的类或结构。

一种方法是为向量的所有“预期”类型提供重载

    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;
    }

    ...

好吧,这是一种非常丑陋的方式,我永远不会在游戏(速度)中使用它,但是它可以满足您的要求:

您的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));

        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM