强制C#泛型类型的任意函数
我想创建一个这样的泛型函数,我打算实例化基本类型,大多数是DateTime,int和字符串。强制C#泛型类型的任意函数
static T MyParameter<T>(string value, T defaultValue)
{
return value.StartsWith("$$") ? defaultValue : T.Parse(value);
}
这不会编译,因为不能保证T会有“解析”。
有没有一种“直接”的方式来实现它? (我的意思是,避免反思或代表做肮脏的工作)。
我找不到任何约束T会做的伎俩。
你可以在分析方法通过为通用情况:
static T MyParameter<T>(string value, T defaultValue, Func<string, T> parse)
{
return value.StartsWith("$$") ? defaultValue : parse(value);
}
但为了方便起见,你可能要为您计划使用的最常见类型的提供重载:
static int MyParameter(string value, int defaultValue)
{
return MyParameter(value, defaultValue, int.Parse);
}
static DateTime MyParameter(string value, DateTime defaultValue)
{
return MyParameter(value, defaultValue, DateTime.Parse);
}
static string MyParameter(string value, string defaultValue)
{
return MyParameter(value, defaultValue, x => x);
}
如果你真的不喜欢这样,你可以使用反射,但我不会推荐它:
static T MyParameter<T>(string value, T defaultValue)
{
if (value.StartsWith("$$"))
{
return defaultValue
}
var method = typeof(T).GetMethod("Parse", new[] { typeof(string) });
return (T)method.Invoke(null, new[] { value });
}
注意:如果您将'method'缓存在字典中,则每个值为T的反射实际上可以更快一些。 (更多的时间用于验证* right *方法)当然,基本类型都实现'IConvertible'。 – 2013-10-08 13:35:28
这应该这样做:
static T MyParameter<T>(string value, T defaultValue)
{
return (T) (value.StartsWith("$$") ? defaultValue : Convert.ChangeType(value, typeof (T)));
}
在泛型上使用约束怎么样?
http://msdn.microsoft.com/en-us/library/d5x73970.aspx
所以,你的方法就变成了:
static T MyParameter<T>(string value, T defaultValue) where T : IParseable
{
return (T)(value.StartsWith("$$") ? defaultValue : defaultValue.Parse(value));
}
当然,这意味着使用的所有类型必须实现IParseable。
这是正确的方法。基本上,您需要使用该类型的协方差来确保它符合您尝试调用的内容。 – Alex
这实际上不会编译。 ** 1)**您试图在'T',** 2)**上静态调用'Parse',除非'IParseable'是通用的(例如'where T:IParseable
是的,你说得对。我修复了#1和#2。 #3,你完全正确。这是这个代码的问题。你基本上必须为所有烦人的基本数据类型编写包装。 – Zippit
恐怕没有。 – MarcinJuraszek
我的一般做法是将'T'约束为'IConverible',并使用'Convert.ChangeType'并将其转换为T来处理。但是,如果您的价值以$$开头,除非您剥离美元符号,否则几乎总是无法解析。 – vcsjones
@vcsjones我认为这就是为什么当'value'以'$$'开始时他返回'defaultValue'的原因。 – MarcinJuraszek