首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Func<...>和行动不统一呢?

为什么Func<...>和行动不统一呢?
EN

Stack Overflow用户
提问于 2015-10-15 13:57:49
回答 2查看 420关注 0票数 15

例如,我一直希望传递一个返回且没有输入的Func,而不是Action

代码语言:javascript
复制
Func<int> DoSomething = ...;

Task.Run(DoSomething);

在哪里,我并不真正关心DoSomething的返回值。

然而,这些类型并不统一,最后我结束了对调用的包装。

代码语言:javascript
复制
Task.Run(() => { DoSomething(); });

有没有办法使这些类型在不包装的情况下统一?还有,它们没有统一的好的设计理由吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-15 15:03:49

您希望下列语句为真:

如果我有一个Func<T>,我应该能够在需要Action的地方使用它。

这将需要Func<T>(A)可分配给Action(B)隐式可转换为Action

如果我们假设(A)需要T (可以是任何类型),则可以分配给void

Eric在他的博客中回答了这个问题

为了从方法组到委托类型的协变返回类型转换,不应该将“void”视为所有可能类型的超级类型吗?

他的回答是“不行”,因为这最终不符合CLI规范。CLI规范要求返回值必须放在堆栈上,这样void函数就不会生成"pop“指令,而返回某些内容的函数就会生成"pop”指令。如果有某种方法可以有一个包含void函数或返回在编译时不知道的函数的“操作”,那么编译器将不知道是否要生成"pop“指令。

他接着说:

如果CLI规范说“任何函数的返回值都在‘虚拟寄存器’中传回”,而不是将其推到堆栈上,那么我们就可以使返回的委托与返回任何内容的函数兼容。您可以始终忽略寄存器中的值。但这不是CLI指定的,所以这不是我们能做的。

换句话说,如果存在存储函数返回值的“虚拟寄存器”(大概在CLI规范中不存在),那么C#及其编译器的编写人员本来可以做您想做的事情,但是他们不能这样做,因为他们不能偏离CLI规范。

如果我们假设(B),就会发生重大变化,正如Eric在这个博客中所解释的那样。将他博客中的例子改编成这样,如果有一个从Func<T>Action的隐式转换,一些程序将不再编译过去的程序(中断更改)。这个程序目前正在编译,但是尝试不注释隐式转换操作符,类似于您所要求的,它不编译。

代码语言:javascript
复制
public class FutureAction
{
    public FutureAction(FutureAction action)
    {
    }

    //public static implicit operator FutureAction(Func<int> f)
    //{
    //    return new FutureAction(null);
    //}

    public static void OverloadedMethod(Func<FutureAction, FutureAction> a)
    {
    }

    public static void OverloadedMethod(Func<Func<int>, FutureAction> a)
    {
    }

    public static void UserCode()
    {
        OverloadedMethod(a => new FutureAction(a));
    }
}

(显然,这并不是他们要做的,因为这只适用于Func<int>,而不是Func<T>,但它说明了问题所在。)

摘要

我认为您所面临的问题是CLI规范的一个工件,这在当时可能是没有被忽略的,我猜他们不想引入破坏性的更改,以允许隐式转换才能正常工作。

票数 6
EN

Stack Overflow用户

发布于 2015-10-15 14:29:24

CLI标准中拔出

二.4.6.1代表签名兼容性 只有在以下情况下,委托才能可验证地绑定到目标方法:

  1. 目标方法的签名是委托-可指派的-委托给委托的签名;

..。

T类型的目标方法或委托是委派给D类型的委托的当且仅当以下所有情况都适用:

  1. T的返回类型U和D,V的返回类型V是可以分配给U的。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33150506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档