【问题标题】:Why does the use of dynamic variables break my code at runtime? [duplicate]为什么使用动态变量会在运行时破坏我的代码? [复制]
【发布时间】:2017-10-25 23:20:00
【问题描述】:

我已经调试这个问题几个小时,终于找到了问题的罪魁祸首。让我解释一下设置。

(我有这些接口和实现它们 A、B 的类)

public interface IA { public void DoSomething(int i); }
public interface IB : IA { public void SomethingElse(); }

(在某个类的某个方法中)

dynamic options = JSonConvert.DeserializeObject<dynamic>(json);
var id = int.Parse(options.someId.ToString());

IB b = new B();
b.DoSomething(id);

此代码按预期编译,但在运行时我得到“IB 不包含 'DoSomething' 的定义”。

但是,如果我改为:

var id = 1;
IB b = new B();
b.DoSomething(id);

然后一切正常!

以前我在方法中使用动态时也发生过类似的事情。这里发生了什么?有人知道吗?

注意:我可以通过将两条线移到不同的方法来轻松避免这种情况,或者完全避免使用动态,但我只是好奇为什么:)

有趣的事实:当我在一个接口和一个类中包含“DoSomething”和“SomethingElse”时,这并没有造成任何问题......

【问题讨论】:

  • 动态传染。 id 是动态的,因此编译器拒绝对其进入的任何方法返回的任何内容做出任何假设。一切都被视为动态的,并且规则不同。试试int id = (int)options.someId; 或其他什么,看看会发生什么。
  • 你能显示为真实代码吗?考虑准备mcve
  • @DiskJunky 当涉及dynamic 时,在运行时进行重载解析。编译器不知道实际会调用什么方法。很可能是爷爷的老熟人int.Parse(),但“很可能”并不合适。
  • 您可以通过将鼠标悬停在var 上来验证所有这些。使用 dynamic 时永远不要假设类型,因为你实际上是在扔掉打字系统。
  • @AndersLindas 正常调用int.Parse();没有超载的。问题在于,对于dynamic,编译器假定可能存在,所以它只是说“废话,这都是动态的,无论如何”——那么b就是dynamic,它意味着它在运行时解析方法调用,并且运行时方法解析忽略基类或其他东西,我不记得确切的细节。但这就是失败的地方:在运行时解析方法的工作方式不同,它在运行时解析DoSomething(),因为上游有一个dynamic

标签: c# dynamic runtime-error


【解决方案1】:

正如@EdPlunkett 所指出的,使用“int”而不是“var”确实有效。如果您阅读第一篇文章中的 cmets,您会发现他对为什么会发生这种情况的解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 2014-03-24
    • 2018-06-23
    • 1970-01-01
    • 2011-02-25
    • 2014-04-08
    相关资源
    最近更新 更多