2012-08-05 29 views
1

我想創建泛型函數Math.Abs​​(),但我不知道如何做到這一點。 如果我創建一個類數學我不能創建T值的方法Abs因爲我不知道T的類型。Math.Abs​​(T值)的泛型C#

如果有人知道如何做到這一點?

感謝

+0

我不知道C#的泛型,但至少在C++中;你可以創建一個泛型函數,它假設一個類型的操作符已經被重載,如果te類型沒有,那麼編譯時就會拋出一個異常。 – 2012-08-05 17:56:27

+0

我會遵循這種模式:http://stackoverflow.com/questions/63694/creating-a-math-library-using-generics-in-c-sharp – 2012-08-05 17:56:55

+0

@ RichardJ.RossIII:請注意,在C#中,你不能確保一個方法有運算符重載(它們是靜態方法,我討厭這種c#行爲)。這就是說,如果一個對象是一個帶有泛型子句的數字,你就不能真正「理解」它。 – 2012-08-05 17:58:24

回答

6

六個選項:基於T

  • 每種類型的過載的執行時間型

    • 使用反射你關心
    • 使用的if/else對於每一個類型的,你在乎
    • 創建包含Dictionary<Type, Func<object, object>>爲每一個類型的委託你照顧.NET 4的約
    • 使用dynamic

      public T Foo<T>(T value) 
      { 
          dynamic d = value; 
          return Math.Abs(d); 
      } 
      
    • 使用像馬克Gravell的的MiscUtil

    generic operators部分,我可能會去,如果可能的過載選項。它會在編譯時適當地限制你,避免任何潛在的耗時的裝箱/反射。

  • 4

    你不能用泛型做到這一點 - 沒有泛型類型的限制,這將確保在傳遞類型是數字類型。

    2

    我認爲這是不合邏輯的寫一個通用的方法,本質上表現不同的東西。浮動和雙精度工作方式類似,但int不以這種方式工作(它們沒有小數部分)。

    爲每個方法編寫一個重載應該是正確的方式來處理這個問題,否則如果typeof基本上是錯誤的,你最終會做一堆。

    1

    您可以通過T.GetType()獲取T的類型。但它不會幫助你。你不能寫通用的方法,但可以寫物體的Abs方法:

    private static object Abs(object num) 
    { 
        var type = num.GetType(); 
        if (type == typeof(Int32)) 
        { 
         return Math.Abs((int) num); 
        } 
        if (type == typeof(Int64)) 
         return Math.Abs((long)num); 
        if (type == typeof(Int16)) 
         return Math.Abs((short)num); 
        if (type == typeof(float)) 
         return Math.Abs((float)num); 
        if (type == typeof(double)) 
         return Math.Abs((double)num); 
        if (type == typeof(decimal)) 
         return Math.Abs((decimal)num); 
        throw new ArgumentException(string.Format("Abs is not defined for type {0}", type.FullName)); 
    }