c#泛型<t> /约束问题</t>

时间:2011-04-01 10:01:54

标签: c# .net

考虑以下例程,通过构建一些默认行为(例如,没有空值,不解析“1,1,1”作为有效数字)来简化我的生活:

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 ..."

通常的“where T:struct”约束在这里是不够的,因为“return(T)0”语句对任意值类型无效。似乎应该有一些方法来泛化它而不向后弯曲,但我没有看到它。我错过了什么?

4 个答案:

答案 0 :(得分:6)

你不能这样做。

.NET中的泛型不是模板,它们只编译一次,因此必须在编译时合法,而不是在调用时。

由于没有where T : number约束或没有where T : op_add()约束,你不能只使用泛型,你需要重载或运行时检查来执行此操作。

答案 1 :(得分:3)

您可以尝试T:IConvertible并更改您的最后一行以返回Convert.ToDouble(O)?我很确定所有的值类型都支持该接口。

答案 2 :(得分:1)

答案 3 :(得分: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方法,可以用于所有你想要的类型。

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