有什么方法可以将Task<T>
的结果向下转换为非通用Task
吗?
我知道这可以用Reflection做,但有没有办法在没有它的情况下做到这一点?也许是通过使用Expression
?
以下是我想要做的一个例子:
RunResult RunTask(Task task)
{
task.Wait();
object result = ???;
if (result is RunResult)
return (RunResult)result;
return RunResult.Success;
}
我知道我可以通过使用不同的重载来实现此目的,但我不喜欢行为根据选择的重载而改变。
如果任务没有结果,那么在这种情况下null就可以了。
答案 0 :(得分:7)
这似乎是Task<RunResult>
,对吧?然后将其转换为该类型并提取结果。
如果我的猜测错了,您可以使用dynamic
快速获取Result
属性的值。
((dynamic)myTask).Result
现在,此结果值的类型为dynamic
,因此我不确定您希望如何从中提取数据。
答案 1 :(得分:3)
如果传入Task<T>
实例,其中Result
是RunResult
派生的内容,您将获得该值作为此函数的返回值。否则,您将获得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;
}