爲了在通用的方法來實現這一點,你需要聲明的是覆蓋EndInvoke
像這樣的擴展方法:
public static class DelegateExtensions
{
public static TResult EndInvoke<TDelegate, TResult>(this TDelegate asyncCaller, IAsyncResult asyncResult) where TDelegate : System.Delegate
{
TResult result = default(TResult);
try
{
result = asyncCaller.EndInvoke(asyncResult);
}
catch (Exception ex)
{
LogExceptionMessageOrWhatever(ex.Message);
throw;
}
return result;
}
}
然而,該程序會生成一個編譯器錯誤。爲什麼? System.Delegate
類是不能在通用約束中使用的特殊類。
所以你不能只是擺脫約束,並使用反射來調用正確的過程?
我想你可以,但是這打破了使用泛型的目的。更好的解決方案是使您的委託通用,然後重寫擴展方法以僅定位該委託。
public delegate TFooResult GetFooAsync<TFooResult>();
public static class GetFooAsyncExtensions
{
public static TFooResult EndInvoke<TFooResult>(this GetFooAsync<TFooResult> asyncCaller, IAsyncResult asyncResult)
{
TFooResult result = default(TFooResult);
try
{
result = asyncCaller.EndInvoke(asyncResult);
}
catch (Exception ex)
{
LogExceptionMessageOrWhatever(ex.Message);
throw;
}
return result;
}
}
現在,你會打電話EndInvoke
像你通常會。該框架將自動使用您的版本。
private void Main()
{
Foo1Result foo1 = null;
var foo1Factory = new GetFooAsync<Foo1Result>(
() =>
{
return new Foo1Result();
});
foo1Factory.BeginInvoke(
callback: asyncResult =>
{
foo1 = foo1Factory.EndInvoke(asyncResult);
},
@object: null);
}
有兩個biltin delegeates在.NET函數功能和行動使用它,它覆蓋90%的情況下 –
Developerzzz
你可以傳遞一個lambda表達式 http://stackoverflow.com/questions/14297633/c-sharp- pass-lambda-expression-as-method-parameter –
我不明白你爲什麼要編寫以委託爲參數的委託。我寫了一個沒有這種嵌套的解決方案。如果這沒有幫助,請用您的實際代碼替換示例。 –