假设我有一个将Task作为对象返回的API:
private static object CreateTask()
{
return Task.Factory.StartNew(() => "Task string");
}
我需要使用一个函数扩展API,该函数返回另一个链接到CreateTask函数返回的Task的Task,以便新Task的结果将是初始Task的结果。即像这样的东西:
private static object WrapTask(dynamic task)
{
object new_task = task.ContinueWith(parentTask => parentTask.Result, TaskContinuationOptions.ExecuteSynchronously);
return new_task;
}
使用示例:
var task = (Task<string>)WrapTask(CreateTask());
Console.WriteLine(task.Result);
应该打印“任务字符串”字符串。
WrapTask函数的问题在于编译器拒绝接受这种结构:
object result = task.ContinueWith(parentTask => parentTask.Result, TaskContinuationOptions.ExecuteSynchronously);
出现以下错误:
Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type
非常感谢有关如何以所述方式扩展API的任何想法。
答案 0 :(得分:2)
您可以使用动态类型来调用动态类型提供的类型推断的泛型方法:
private static object WrapTask(dynamic task)
{
return WrapTaskImpl(task);
}
private static Task<T> WrapTaskImpl<T>(Task<T> task)
{
return task.ContinueWith(parentTask => parentTask.Result,
TaskContinuationOptions.ExecuteSynchronously);
}
根本不清楚这种包装的重点是什么,请注意......以及为什么你只想施放WrapTask
的结果 - 如果你知道的话这是一个任务,为什么不转换CreateTask
的结果,此时你可以简单地调用WrapTask
?或者也许让WrapTask
执行演员表演?
private static Task<T> WrapTask<T>(object task)
{
Task<T> realTask = (Task<T>) task;
return realTask.ContinueWith(parentTask => parentTask.Result,
TaskContinuationOptions.ExecuteSynchronously);
}
然后您的主叫代码变为
var task = WrapTask<string>(CreateTask());
Console.WriteLine(task.Result);