【问题标题】:Passing a method with parameter Func<T> and getting TResult传递带有参数 Func<T> 的方法并获取 TResult
【发布时间】:2014-02-17 07:22:06
【问题描述】:

所以基本上 T 有一个返回类型,我想取回通用返回类型。示例:

private TResult EndInvoke<T, TResult>(Func<T, TResult> asyncCaller, IAsyncResult asyncResult)
{
    TResult result = default(TResult);

    try
    {
        result = asyncCaller.EndInvoke(asyncResult);
    }
    catch (Exception exception)
    {
       // get exception details.
    }

    return result;
}

如何只传递调用方法的 T 并获取 TResult? 请注意,我只有 T。

编辑:我的意思是如何调用这个方法?

编辑:我想要一个通用的 EndInvoke,因为我对不同的 EndInvoke 有很大的尝试,然后我想要 EndInvoke 的结果。

【问题讨论】:

  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • So basically T has a return type 实际上,你有返回类型TResult。问题不清楚。
  • 这个函数看起来它的全部意义(结合另一个函数,可能名为BeginInvoke)是启用异步调用。如果你只有T,想调用asyncCaller,并且想在同一个函数中处理结果,你只能使用同步调用。你能澄清一下你想要做什么吗?
  • 我认为这是不可能的。对于泛型类型,您需要在定义中将类型作为类型参数 T 或 TResult 提及。如果您只想在方法定义中提及 T 而不是 TResult,它怎么知道 TResult 可以是什么?为此,您可以使用动态或对象结果类型。
  • 我强烈建议您考虑将 APM 模式 (IAsyncResult) 转换为任务。您可以使用Task.Factory.FromAsync。任务是强类型的,可以捕获异常并且通常更容易使用。

标签: c# generics func iasyncresult


【解决方案1】:

我建议先将您的通用 EndInvoke&lt;,&gt; 方法转换为扩展方法。

public static class FuncExtensions
{
    public static TResult EndInvoke<T, TResult>(this Func<T, TResult> asyncCaller, IAsyncResult asyncResult)
    {
        // ...
    }
}

这将简化方法调用。例如,我将调用一个计算整数平方的方法。

private int Square(int x)
{
    return x * x;
}

在您的客户端代码中,您可以这样称呼它:

Func<int, int> caller = new Func<int, int>(Square);

int x = 5;

int y = default(int);

caller.BeginInvoke(x,
    asyncResult =>
    {
        y = caller.EndInvoke(asyncResult);
    },
    null);

Console.WriteLine("The square of {0} is {1}", x, y);

编辑

此示例未经任何测试,包含明显的竞争条件。

【讨论】:

    【解决方案2】:

    不确定我的理解是否正确,但我认为如果你想要 Func 返回值,你应该放弃 IAsyncResult。

    例子:

    private TResult GetResult<T, TResult>(Func<T, TResult> asyncCaller, IAsyncResult asyncResult)
        {
            TResult result = default(TResult);
            result = asyncCaller(argument...);
    
            return result;
        }
    

    【讨论】:

    • 问题中的函数名称EndInvokeIAsyncResult 表明已经进行了异步调用。
    猜你喜欢
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多