只要真實的返回值是一個引用類型,它就應該沒問題 - 但這對於值類型返回值失敗是有意義的。 (見埃裏克利珀的約representation and identity職位更詳細的解釋。)
一種選擇是創建一個通用類是這樣的:
public class BoxingParserDelegate<T>
{
private readonly Converter<string, T> parser;
public BoxingParserDelegate(Converter<string, T> parser)
{
this.parser = parser;
}
public object Parse(string x)
{
return parser(x);
}
}
在你GetParser方法,你會檢查是否parse
返回類型是一個值類型,如果是這樣的話,通過反射創建一個BoxingParserDelegate<T>
的實例。然後,您可以從BoxingParserDelegate
的Parse方法創建ParseHandler
實例。
這一切都會坦率地說有些尷尬,但應該工作。說實話,感覺應該有一個更簡單的方法。
(在.NET 3.5或更高版本我推薦使用表達式目錄樹,但我剛剛看到的.NET 2.0的標籤。)
編輯:啊哈,以爲稍微簡單的辦法:
public static ParseHandler BuildParseHandler<T>(Converter<string, T> converter)
{
// Performs boxing automatically
return delegate(string x) { return converter(x); }
}
這是有效要求編譯器爲您完成上述工作的一半。那麼你只需要確定是否需要調用它,並在必要時用反射來完成。類似這樣的:
public static ParseHandler GetParser(Type t)
{
MethodInfo parse = t.GetMethod("Parse",
BindingFlags.Static | BindingFlags.Public,
null, new Type[] { typeof(string) }, null);
// Method not found
if (parse == null)
{
return null;
}
// Reference type - use delegate covariance
if (!parse.ReturnType.IsValueType)
{
return (ParseHandler) Delegate.CreateDelegate(typeof(ParseHandler),
parse, true);
}
// Tricky situation: call BuildParseHandler with generics
Type delegateType = typeof(Converter<,>).MakeGenericType(typeof(string),
parse.ReturnType);
object converter = Delegate.CreateDelegate(delegateType, parse, true);
// You may need extra work to get this... let me know whether or not it works.
// Obviously if you make it private, you'll need extra binding flags.
MethodInfo method = typeof(TypeContainingThisMethod)
.GetMethod("BuildParseHandler");
method = method.MakeGenericMethod(parse.ReturnType);
return (ParseHandler) method.Invoke(null, new object[] { converter });
}
您是否嚴格禁用.NET 2.0平臺? – 2011-03-10 18:01:26
你能向我們展示它失敗的'Parse'方法的聲明嗎? – Ani 2011-03-10 18:03:44
也許你想寫的東西就像我的'解析'https://github.com/CodeInChaos/ChaosUtil/blob/master/Chaos.Util/Conversion.cs,除非你可能需要替換一些'T'對象。 –
CodesInChaos
2011-03-10 18:09:01