2011-11-12 6 views
22

Dlaczego kompilator C# nie mówi mi, że ten fragment kodu jest nieprawidłowy?Dlaczego kompilator C# nie sprawdza "statyczności" metody w miejscu wywołania z argumentem dynamicznym?

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

    public void MyMethod(int i) 
    { 
     Console.WriteLine("int"); 
    } 
} 

Wezwanie do MyMethod nie w czasie wykonywania, ponieważ staram się wywołać non-statycznej metody z metody statycznej. To bardzo rozsądne, ale dlaczego kompilator nie uważa tego za błąd podczas kompilacji?

Następujące nie skompilować

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

tak pomimo dynamicznego wysyłki, kompilator musi sprawdzić, MyMethod istnieje. Dlaczego nie sprawdza "statyczności"?

Odpowiedz

14

Skuteczność przeciążania jest tutaj dynamiczna. Widoczny w tym fragmencie kodu:

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"); 
    } 
} 

Działa prawidłowo. Teraz przypisz 1 do d i zanotuj awarię środowiska wykonawczego. Kompilator nie może rozsądnie emulować dynamicznej rozdzielczości przeciążania w czasie kompilacji, więc nie próbuje.

+2

Ale jeśli nie istnieje metoda instancji o nazwie "MyMethod", to * powinna * być w stanie wygenerować błąd kompilacji ???? Wygląda na to, że kompilator jest wystarczająco inteligentny, aby zobaczyć, czy MyMethod "w ogóle nie istnieje ... więc twoja odpowiedź mnie jeszcze nie przekonała ... może mógłbyś rozwinąć nieco więcej? :-) –

+1

Nie rozumiem dlaczego (czas pracy) Rozdzielczość przeciążenia bierze pod uwagę metody instancji, gdy strona wywołania jest w statycznej metodzie – CodesInChaos

+1

Ponieważ stara się wygenerować dobrą diagnostykę Czy programista zapomniał dodać przeciążenie? Czy może zapomniał statycznego słowa kluczowego? –

0

Gdy kompilator wykryje operację na/ze zmienną typu dynamic, wyśle ​​tę informację za pomocą obiektu CallSite. (Obiekt CallSite jest informacją o wywołaniu.)

W pierwszej próbce może się skompilować, ponieważ kompilator może emitować informacje (np. Typ połączenia, metodę, do której chcesz zadzwonić itp.). W drugim kodzie próbujesz wywołać metodę, która nie istnieje, więc kompilator nie może wyemitować kodu IL dla ciebie.

+0

Dziękuję za poświęcony czas.Nie pytam, dlaczego drugi przykład się nie kompiluje i całkowicie zgadzam się, że kompilator może emitować IL dla pierwszego przykładu. Pytam zasadniczo, dlaczego pozwala na pierwszy przykład? Dlaczego nie pomaga mi pamiętać o dodaniu statycznego słowa kluczowego do MyMethod? – Rune

Powiązane problemy