Почему компилятор С# не проверяет "статичность" метода на сайтах вызовов с динамическим аргументом?
Почему компилятор С# не говорит, что этот фрагмент кода недействителен?
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
. Почему он не проверяет "статичность"?
Ответы
Ответ 1
Разрешение перегрузки здесь динамическое. Видимый в этом фрагменте кода:
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 и обратите внимание на сбой выполнения. Компилятор не может разумно эмулировать динамическое разрешение перегрузки во время компиляции, поэтому он не пытается.
Ответ 2
Когда компилятор обнаружил операцию с/с переменной типа dynamic
, она будет передавать эту информацию с помощью объекта CallSite
. (Объект CallSite хранит информацию о вызове.)
В вашем первом примере он может скомпилироваться, потому что компилятор может испускать информацию (например, тип вызова, метод, который вы хотите вызвать и т.д.). Во втором коде вы пытаетесь вызвать метод, который не существует, поэтому компилятор не может испустить код IL для вас.