获取非通用任务的结果

时间:2014-05-23 21:23:34

标签: c# .net

有什么方法可以将Task<T>的结果向下转换为非通用Task吗? 我知道这可以用Reflection做,但有没有办法在没有它的情况下做到这一点?也许是通过使用Expression? 以下是我想要做的一个例子:

RunResult RunTask(Task task)
{
    task.Wait();

    object result = ???;

    if (result is RunResult)
        return (RunResult)result;

    return RunResult.Success;
}

我知道我可以通过使用不同的重载来实现此目的,但我不喜欢行为根据选择的重载而改变。

如果任务没有结果,那么在这种情况下null就可以了。

3 个答案:

答案 0 :(得分:7)

这似乎是Task<RunResult>,对吧?然后将其转换为该类型并提取结果。

如果我的猜测错了,您可以使用dynamic快速获取Result属性的值。

((dynamic)myTask).Result

现在,此结果值的类型为dynamic,因此我不确定您希望如何从中提取数据。

答案 1 :(得分:3)

如果传入Task<T>实例,其中ResultRunResult派生的内容,您将获得该值作为此函数的返回值。否则,您将获得null

RunResult RunTask(Task task)
{
    task.Wait();
    var type = task.GetType();
    if (!type.IsGenericType)
    {
        return null;
    }
    //Could also use: ((dynamic)task).Result as RunResult
    return type.GetProperty("Result").GetValue(task) as RunResult;
}

答案 2 :(得分:2)

Task不公开“结果”属性,并且因为Task不是逆变的(即<T>不是<out T>),所以不能简单地转换为Task<object>

除了反射之外的一种方法是使用通用方法处理代码。由于方法可以是泛型,您可以将其传递给任务。这样做的另一个好处是,您可以在不显式设置通用参数的情况下调用该方法,因为它们可以通过编译器的使用来推断。

RunResult RunTask<T>(Task<T> task)
{
    task.Wait();

    T result = task.Result;

    if (result is RunResult)
        return (RunResult)result;

    return RunResult.Success;
}