C# 中返回 void 的方法的动态类型参数
下面的代码生成异常:
未处理的异常: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:无法隐式地将类型“void”转换为“对象”
var m = M((dynamic)d); //Exception thrown here
private void M(Int32 n) { Console.WriteLine("M(Int32): " + n); }
我认为应该将 null 分配给 m 变量而不是异常。
有什么想法吗?
编辑
请注意,下面会生成编译时错误
dynamic result = M(1);//compile time error: Cannot implicitly convert type 'void' to 'dynamic'
private void M(Int32 n) { }
The code below generates exception:
Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type 'void' to 'object'
var m = M((dynamic)d); //Exception thrown here
private void M(Int32 n) { Console.WriteLine("M(Int32): " + n); }
I think that null should be assigned to the m variable instead of exception.
Any idea?
Edit
Please note that below generates compile time error
dynamic result = M(1);//compile time error: Cannot implicitly convert type 'void' to 'dynamic'
private void M(Int32 n) { }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通常,像这样的问题可以通过规范参考来回答,该规范参考表明编译器/运行时实际上正在做正确的事情。在这种情况下,规范的相关部分(7.2.2)相对沉默。它基本上表示确切的细节是特定于实现的。
但是,我认为它正在做正确的事情:如果您认为动态类型粗略地翻译为让编译器以相同的方式操作,但使用执行时的表达式的实际类型时间,那么出现执行时间错误是完全合理的。调用 void 方法时的正常编译器行为是禁止将其用作赋值表达式的右侧,那么为什么仅仅因为绑定是在执行时完成的,就应该改变这种情况呢?
Normally questions like this are answered with a specification reference showing that the compiler / run-time is actually doing the right thing. In this case, the relevant section of the spec (7.2.2) is relatively silent. It basically says that the exact details are implementation-specific.
However, I would argue that it's doing the right thing: if you think of dynamic typing as roughly translating to letting the compiler operate in the same way, but using the actual types of expressions as they are at execution time, then it's entirely reasonable to have an execution time error. The normal compiler behaviour when calling a void method is to prohibit using it as the right-hand side of an assignment expression, so why should that change just because the binding is done at execution time?