2011-07-01 37 views
5

我正在嘗試編寫處理不同數字類型的類。我知道C#(和.Net在一般情況下,我認爲)沒有INumber接口,所以我不能使用類似以下內容:如何編寫單個類以多次編譯不同的數字類型?

public class Adder<T> where T:INumber 
    { 
     public T Add(T a, T b) 
     { 
      return a + b; 
     } 
    } 

這沒關係,不過,因爲我想避免裝箱/拆開我的每一個號碼。我可以,但是,使用條件編譯每種類型的我想支持:

#if FLOAT 
    public class AdderF 
    { 
     public float Add(float a, float b) 
#else 
    public class Adder 
    { 
     public int Add(int a, int b) 
#endif 
     { 
      return a + b; 
     } 
    } 

這意味着我需要編寫不同的Library.dllLibraryF.dll,但是。有沒有更優雅的解決方案呢?

顯然,在我的例子中,我可以簡單地編寫代碼兩次。然而,我想使用這個過程來創建一個整數版本和浮點版本的大型複雜數據結構,所以當更新我的結構時,不希望發生複製粘貼錯誤。我也不希望速度損失將浮點結構包裝在整體包裝中,並且不必要地將所有輸入轉換爲更寬鬆的數據類型。

回答

3

我想這取決於你想要它有多嚴格。你想要一個Add方法只接受兩個完全相同類型的參數(int和int,float和float)......?如果沒有,性能也不是非常重要,那麼你可以用decimal來實現你的解決方案,它將全部工作。

如果確實必須嚴格,並且您希望每種類型的特定版本,則可能需要考慮T4代碼生成。它類似於C++的模板(有些人認爲C++模板和C#泛型是相同的,但它們不是)。

Scott Hanselman寫了關於它的an interesting article

+0

就像我說的,我試圖哄騙更多的性能,我的數據結構,我認爲在我可以使用'int'的時候在任何地方使用'decimal'都是有效的。 T4絕對是一個我不知道的很酷的技術,並且一定會對它進行研究! – dlras2

3

也許這可能是有用的:Is there a C# generic constraint for "real number" types?

看來,它不是像你說的那樣直接可能。擁有它會很有用。

+0

謝謝!我正在尋找一個像這樣的鏈接來包含我的問題。我知道我可以使用這樣的抽象計算器來處理各種數字類型,但是我的要點是,當浮點精度不是必需的時候,可以使用整數結構來提高性能。 – dlras2

2

這裏的主要挑戰是抖動必須發出不同的操作碼,具體取決於您是否添加浮點數或整數,因此,即使代碼看起來相似,但實際上在幕後非常不同。這在C++中是可行的(因爲模板是爲每個類型定義單獨編譯的),但.NET泛型的工作方式不同。看看T4 templates作爲一個可能的解決方案(如果你真的需要能夠分別編譯爲float或int)

+0

+1,用於解釋C++模板與.Net泛型以及T4建議。 – dlras2

+1

我實際上有點失望,因爲編譯器可以支持一個允許發出Add IL OpCode的'數字'約束(與嘗試解析'add'操作符相反),使用類型特定的jitting來處理差異。這仍然會造成一些限制,因爲對於整數有一個單獨的Add.Ovf指令,所以您只能在不進行整數溢出檢查的情況下支持添加。編譯器還需要特殊的支持來理解還不是特定類型的「原始數字」,爲Lippert先生創造有趣的新邊界案例。 –

相關問題