Почему компилятор c # не проверяет «статичность» метода на сайтах вызовов с динамическим аргументом? - PullRequest
22 голосов
/ 12 ноября 2011

Почему компилятор 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 существует.Почему он не проверяет «статичность»?

Ответы [ 2 ]

14 голосов
/ 12 ноября 2011

Разрешение перегрузки здесь является динамическим.Видно в этом фрагменте кода:

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 и обратите внимание на сбой во время выполнения.Компилятор не может разумно эмулировать динамическое разрешение перегрузки во время компиляции, поэтому он не пытается.

0 голосов
/ 12 ноября 2011

Когда компилятор обнаружил операцию над / с переменной типа dynamic, он выдаст эту информацию, используя объект CallSite. (Объект CallSite хранит информацию о вызове.)

В вашем первом примере он может компилироваться, потому что компилятор может выдавать информацию (например, тип вызова, метод, который вы хотите вызвать и т. Д.). Во втором коде вы пытаетесь вызвать метод, который не существует, поэтому компилятор не может создать для вас IL-код.

...