2011-04-01 122 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();