T型默认值

时间:2016-11-23 21:45:09

标签: c# types extension-methods

我有几种扩展方法,例如ParseIntParseLongParseByte。现在,我试图为所有这些方法制作一个扩展方法。问题是要使Default参数可选,我必须给它一个类似T Default = 0的值,但它会生成错误:

  

类型' int'的值不能用作默认参数,因为没有标准转化可以输入' T'

如果我像T Default = (T)0那样使用它,那么我会收到另一个错误:

  

无法转换类型' int'到了'

这是我的扩展方法:

public static T Parse<T>(this string x, T Default = 0)
        {
            Type type = typeof(T);
            if(type == typeof(int))
            { if(!string.IsNullOrEmpty(x) int.TryParse(x , out Defualt); return Default;  }
        }

2 个答案:

答案 0 :(得分:6)

您可以改为使用default(T)

public static T Parse<T>(this string x, T defaultValue = default(T))

但是,我强烈质疑这里的设计 - 你并不是真的在编写泛型方法,而是一种接受一组特定类型并以不同方式处理每种类型的方法。有时会强制执行此操作,但我通常会Dictionary<T, SomeDelegate>尝试更干净地处理它。

此外,您仍然会在调用int.TryParse时遇到问题 - 您无法将参数Parse<T>用作参数 - 您需要以下内容:

if (typeof(T) == typeof(int))
{
    // You need to consider what you want to happen if
    // int.TryParse returns false - do you want to return 0,
    // or defaultValue?
    int ret;
    if (int.TryParse(x, out ret))
    {
        // Annoying but required due to which conversions are available
        return (T)(object) ret;
    }
}
return defaultValue;

答案 1 :(得分:1)

与已经提到的另一个答案一样,您可以在案例中使用default关键字default(T)获取泛型类型的默认值作为编译时常量。

  • 如果T是类或接口类型,default(T)是空引用。
  • 如果T是结构,则default(T)是所有位均为零的值。数字类型为0falsebool,自定义struct的这两项规则组合。

但是:不要这样做。当它只适用于几种精心挑选的类型时,不要创建这种通用方法。作为一般规则,通用方法适用于所有类型。 (您可以使用通用参数约束where T : …约束有效类型,但这不会改变基本思想。)

在您的情况下,通用方法仅适用于intlongfloatdoubledecimal等几种类型,您甚至必须在通用方法中检查这些类型,以便您可以遵循正确的方法(int.TryParsedouble.TryParse等)。这是一个很重要的信号,表明你的方法根本不应该是通用的。

继续使用之前的扩展方法ParseIntParseSingleParseDouble这是更好的设计。