我有几种扩展方法,例如ParseInt
,ParseLong
,ParseByte
。现在,我试图为所有这些方法制作一个扩展方法。问题是要使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; }
}
答案 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)
是所有位均为零的值。数字类型为0
,false
为bool
,自定义struct
的这两项规则组合。但是:不要这样做。当它只适用于几种精心挑选的类型时,不要创建这种通用方法。作为一般规则,通用方法适用于所有类型。 (您可以使用通用参数约束where T : …
约束有效类型,但这不会改变基本思想。)
在您的情况下,通用方法仅适用于int
,long
,float
,double
,decimal
等几种类型,您甚至必须在通用方法中检查这些类型,以便您可以遵循正确的方法(int.TryParse
,double.TryParse
等)。这是一个很重要的信号,表明你的方法根本不应该是通用的。
继续使用之前的扩展方法ParseInt
,ParseSingle
,ParseDouble
等这是更好的设计。