当前位置: 首页 > 编程语言 > C#

无法将类型’Task ‘转换为’Task ‘分享

时间:2023-04-10 20:51:22 C#

C#学习教程:无法将类型“任务”转换为“任务”publicvoidBar(Funcfunc){thrownewNotImplementedException();我还有一个函数,它接受一个参数作为IMessage的实例并返回一个任务。Message和Result分别是IMessage和IResult的实现。privateTaskDoSomething(Messagem){returnnewTask(()=>newResult());当我将DoSomething传递给Bar时,出现错误。Bar(m=>DoSomething((Message)m));//无法将类型“Task”转换为“Task”为什么Result没有隐式转换为IResult?我认为这是协方差的问题。但是,在本例中,Result实现了IResult。我还尝试通过创建接口并将TResult标记为协变来解决协变问题。publicinterfaceIFoo{voidBar(Funcfunc);但我得到错误:无效方差:类型参数'TResult'必须在IFoo.Bar(Func)中。'TResult'是协变的。现在我卡住了。我知道我有协方差问题,但我不知道如何解决。有任何想法吗?编辑:这个问题是特定于任务的。我通过在我的应用程序中实现异步等待遇到了这个问题。我遇到了这个通用实现并添加了一个任务。其他人可能在这样的转换过程中遇到了同样的问题。解决方案:这是基于以下答案的解决方案:Funcconvert=asyncm=>awaitm;Bar(m=>convert(DoSomething((Message)m)));C#不允许调用类已进行更改以仅允许使用引用类型参数化的接口和委托。任务是一个类。这有点不幸,因为Task是少数可以安全协变的类之一。但是,将Task转换为Task很容易。只需创建一个辅助方法/lambda,它接受一个Task并返回一个Task,等待传入的Task,并将值转换为一个Base。C#编译器会处理剩下的事情。当然,你失去了参考身份,但你不会在课堂上得到它。似乎必须有一种更简洁的方法,但可以创建正确类型的包装器任务。我引入了一个名为GeneralizeTask()的新函数。任务GeneralizeTask(任务任务)whereTDerived:TBase{varnewTask=newTask(()=>{if(task.Status==TaskStatus.Created)task.Start();task.Wait();return(TBase)task。结果;});返回新任务;编辑:正如@EricLippert指出的那样,这可以大大简化。我首先尝试找到这种方法来执行此操作,但找不到可以编译的方法。事实证明,真正的解决方案比我想象的还要简单。asyncTaskGeneralizeTask(Tasktask)whereTDerived:TBase{return(TBase)awaittask;然后你可以像这样调用Bar()。以上是C#学习教程:无法将'Task'类型转换为'Task'分享的全部内容。如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——Bar(m=>GeneralizeTask(DoSomething((Message)m)));本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: