为什么编译器将Func <dynamic,int =“”>的返回类型视为强类型?</dynamic,>

时间:2014-01-24 18:43:19

标签: c# dynamic func

为什么以下编译?看起来编译器有足够的信息知道尝试的分配是无效的,因为Func&lt;&gt;的返回类型。不是动态的。

Func<dynamic, int> parseLength = whatever => whatever.Length;
dynamic dynamicString = "String with a length";
DateTime wrongType = parseLength(dynamicString);

3 个答案:

答案 0 :(得分:7)

  

似乎编译器有足够的信息知道尝试的赋值无效,因为Func<>的返回类型不是动态的。

警告:当然我不再代表C#设计团队了;这些是我对语言设计的看法。

所以你在这里说的是&#34;我已经禁用了安全系统。当我做一些危险的事情并阻止我时,为什么残疾人安全系统没有检测到?&#34;那么,如果这就是你想要的,那么也许你不应该首先禁用那个安全系统。

那说,你是对的; &#34;禁用&#34;类型安全系统实际上可以继续在这里工作并检测到你正在做一些危险的事情。实际上存在许多情况,其中足够聪明的编译器可以对动态子表达式进行类型推导。你找到了其中一个。实现必要的分析是一项功能请求。

所以现在相关的问题是:你希望削减C#的哪个特性,以便为开发团队提供预算来设计,规范,实现,测试,调试,发布和维护静态的功能在程序中发现一个错误,开发人员明确要求关闭静态检查?请记住,费用包括确保语言的未来功能不会干扰编译器进行此扣除的能力;其中一些成本是设计团队将来支付的税款。

少数情况,其中静态分析包含dynamic的表达式;例如,存在一些涉及带动态参数的静态方法的重载解决问题,其中编译器可以并且确实发现无论在运行时提供什么,重载解析都将失败。但除了这几个案例之外,语言设计团队一直认为,将有限的预算花在像您已经确定的方案上这样的预算并不是一件好事。

答案 1 :(得分:2)

由于输入是动态的,编译器甚至无法确定函数的结果是否为int。它将尝试在执行函数时将结果转换为int,如果无法执行则会失败。现在,如果你问为什么你甚至可以允许构造这样的代码,因为静态类型约束无法强制执行 - 请记住,动态不是一个类型,而是作为“你的正常静态类型规则”的警告标志在这里申请“。

查看“动态传染”的概念,以获得更多见解。

答案 2 :(得分:2)

"The type is a static type, but an object of type dynamic bypasses static type checking."

如果您的类型的任何部分是动态的,编译器必须将整个事物视为动态的。所以:

Func<dynamic, int> parseLength = <some func>  // is dynamic and type cannot be evaluated until runtime.

所以编译器允许这段代码:

DateTime wrongType = parseLength

这将编译,并且如您所料,将产生运行时错误。

动态类型在某些情况下很有用。我个人对这种价值的体验是访问COM组件中的非托管代码。

它基本上告诉编译器,“相信我,这会起作用。=)”或者,“这些不是你正在寻找的机器人”