在C#中定義泛型能夠達到代碼的重複利用,可是如何將泛型方法限制爲數值類型(如int,double,float 等)並對其進行進行四則運算呢?html
其實:C#不支持這一點。Hejlsberg描述了不實現此特性的緣由。在接受布魯斯·埃克爾的採訪時:數組
如今還不清楚增長的複雜性是否值得你獲得的小收益。若是在約束系統中不直接支持要作的事情,能夠使用工廠模式來完成。你能夠Matrix<T>
例如,在這方面Matrix
您想要定義一個點乘積方法。固然,這意味着你最終須要了解如何將2相乘。T
S,但你不能說這是一種約束,至少若是T
是int
, double
,或float
..但你能作的就是Matrix
把論點看成論據Calculator<T>
,以及Calculator<T>
,有一個名爲multiply
..你去實現它,而後把它傳遞給Matrix
.code
那麼若是咱們須要一個求數組和的泛型方法怎麼辦?htm
咱們不妨使用下列方法實現ip
public static T Sum<T>(params T[] values) where T:struct { //邏輯實現部分 }
首先咱們應該知道struct的範圍要遠大於數值類型;即(int,float,double 等)是struct的一部分,退而求其次,咱們將輸入的值限制爲struct,那麼能夠很大程度上將輸入值限制;ci
那麼struct值類型提供了以下Equals、GetType、GetHashCode、ToString四個方法,系統並沒有提供四則運算的方法,咱們如何對其數組進行求和呢?get
接下來咱們不妨以下操做:it
public static T Sum<T>(params T[] values) where T:struct { if (values == null) return default(T); dynamic sum = default(T); var type = Type.GetTypeCode(values[0].GetType()); switch (type) { case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Single: case TypeCode.Double: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Decimal: { dynamic vas = values; for (int i = 0; i < vas.Length; i++) { sum += vas[i]; } } break; default: break; } return sum; }
借用dynamic的特性咱們能夠將輸入值轉換成dynamic而後在進行四則運算;class
特別提醒:此方法雖然能夠實現數值類型的求和可是對於一些無四則運算的struct會產生異常操做,咱們能夠在進行數值運算前進行類型判斷,若類型無四則運算操做則特別處理,泛型
在一些取捨下,上述方法也是一個不錯的方法;