为什么c#编译器在具有动态参数的调用站点检查方法的“静态”?

为什么C#编译器不告诉我这段代码无效?

class Program { static void Main(string[] args) { dynamic d = 1; MyMethod(d); } public void MyMethod(int i) { Console.WriteLine("int"); } } 

MyMethod的调用在运行时失败,因为我试图从静态方法调用非静态方法。 这是非常合理的,但为什么编译器在编译时不认为这是一个错误?

以下内容无法编译

 class Program { static void Main(string[] args) { dynamic d = 1; MyMethod(d); } } 

所以尽管动态调度,编译器确实检查MyMethod存在。 为什么不validation“静态”?

这里的过载分辨率是动态的。 在此代码段中可见:

 class Program { public static void Main() { dynamic d = 1.0; MyMethod(d); } public void MyMethod(int i) { Console.WriteLine("int"); } public static void MyMethod(double d) { Console.WriteLine("double"); } } 

工作良好。 现在将1分配给d并记下运行时故障。 编译器无法在编译时合理地模拟动态重载决策,因此它不会尝试。

当编译器在/ dynamic类型的变量上找到操作时,它将使用CallSite对象发出该信息。 (CallSite对象是有关呼叫的商店信息。)

在第一个示例中,它可以编译,因为编译器可以发出信息(例如,调用类型,要调用的方法等)。 在第二个代码中,您尝试调用不存在的方法,因此编译器无法为您发出IL代码。