簡體   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