2011-04-01 63 views
3

考慮下面的例程,它通過構建一些默認行爲(例如,沒有空值,不解析「1,1,1」作爲有效數字)來簡化我的生活:c#泛型<T> /約束問題

public static Double CvtToDouble(Object O) 
    { 
    if (O == null) return (Double)0; 
    if (O == System.DBNull) return (Double)0; 
    if (O is string) return Double.Parse((String)O, 
            System.Globalization.NumberStyles.Float); 
    return (T)O; 
} 

然後對所有的num類型重複這個例程。我想將它們組合都在打字和錯別字保存到

public static T CvtTo<T>(Object O) : where T : "is one of Int32, Int16 ..." 

通常「其中T:結構」的約束是遠遠不夠的在這裏,因爲「回報(T)0」語句是對任意值類型無效。似乎應該有某種方式來通用化,而不是向後彎曲,但我沒有看到它。我錯過了什麼?

回答

6

你不能這樣做。

.NET中的泛型不是模板,它們只編譯一次,因此在編譯時必須合法,而不是在調用時。

由於沒有where T : number約束或無約束where T : op_add(),你不能只用泛型做到這一點,您可能需要過載或運行時檢查,以做到這一點。

3

您可以嘗試其中T:IConvertible和改變你的最後一行返回Convert.ToDouble(O)?我很確定所有的值類型都支持這個接口。

1

您可能需要考慮一個靜態類,它包含每個或所列類型的擴展方法,以便爲每個目標類型提供CvtToDouble()擴展方法;

static class CvtToDoubleExtension 
{ 
    static double CvtToDouble(this int arg) 
    { 
     return (double)arg; 
    } 

    static double CvtToDouble(this string arg) 
    { 
     return double.Parse(arg); 
    } 

    // Etc.... 
} 

它不是整齊如您所需的通用方法,但它只有1級,然後CvtToDouble方法將BEA提供給您的所有需要​​的類型。

string example = "3.1412"; 
double value = example.CvtToDouble();