我正在编写一个泛型方法,我希望根据泛型 Type 参数的类型出现不同的执行路径。不同的执行路径是静态类型的,例如
public static T Get<T>(this NameValueCollection collection, string name) where T : struct
{
//Perform test on type, if it matches, delegate to statically typed method.
if (typeof(T) == typeof(int)) return (T)(object)GetInt32(collection, name);
else if (typeof(T) == typeof(DateTime)) return (T) (object) GetDateTime(collection, name);
//Other types parsed here...
//If nothing matched, return default.
return default(T);
}
我发现能够使用静态执行路径的返回结果的唯一方法是将其装箱为对象,然后将其转换为“T”。
对我来说,这首先违背了使用泛型方法的目的(除了获得一些语法糖)。在我们已经确定 T 是 int 类型的情况下,有谁知道一种能够将 int 值返回为 T 的方法?
我正在考虑使用“动态”类型的 var,但读到它只是在幕后使用对象结束。
这也许是泛型的范围吗?
--
更新以包括我的最终方法,基于 smartcaveman 的回复,它使用通用静态类的类型解析来确定使用哪种“解析”方法,无需装箱或使用动态。
public class StringParser
{
private class Getter<T>
{
private static readonly ConcurrentDictionary<StringParser, Getter<T>> Getters = new ConcurrentDictionary<StringParser, Getter<T>>();
public Func<string, T> Get { get; set; }
private Getter() {}
public static Getter<T> For(StringParser stringParser)
{
return Getters.GetOrAdd(stringParser, x => new Getter<T>());
}
}
public virtual T Get<T>(string value)
{
var get = Getter<T>.For(this).Get;
if (get == null) throw new InvalidOperationException(string.Format("No 'get' has been configured for values of type '{0}'.", typeof (T).Name));
return get(value);
}
public void SetupGet<T>(Func<string, T> get)
{
Getter<T>.For(this).Get = get;
}
}
使用相当简单:
public static void Usage()
{
StringParser parser = new StringParser();
parser.SetupGet(Int32.Parse);
int myInt = parser.Get<int>("3");
}
smartcaveman 方法的窍门在于,具有不同类型参数的泛型静态类实际上被认为是不同的类型,并且不共享静态成员。
很酷的东西,谢谢!