为了以通用方式实现这一点,您需要声明一个覆盖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);
}