C#泛型<T> / 约束问题

3
考虑下面这个例程,它通过内置一些默认行为(例如:没有空值,不将“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个回答

6

你做不到。

.NET中的泛型不是模板,它们只编译一次,因此必须在编译时合法,而不是在调用时。由于没有“where T : number”约束或“where T : op_add()”约束,因此您无法仅使用泛型来实现此操作,您需要重载或运行时检查才能实现。


3
你可以尝试使用 where T : IConvertible,并将最后一行更改为 return 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....
}

虽然它不像你期望的通用方法那样整洁,但它只需要一个类,然后CvtToDouble方法将可用于所有你需要的类型。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接