Piękne pytanie! Chciałbym dodać nieco dłuższe wyjaśnienie dla tych, którzy na co dzień nie robią C # ... ponieważ to pytanie jest dobrym przypomnieniem ogólnych problemów z rozwiązywaniem nazw.
Weź oryginalny kod, nieznacznie zmodyfikowany w następujący sposób:
- Wydrukujmy nazwy typów zamiast porównywać je jak w oryginalnym wyrażeniu (tj
return this is Sparta
.).
- Zdefiniujmy interfejs
Athena
w Place
nadklasie, aby zilustrować rozwiązywanie nazw interfejsów.
- Wydrukujmy również nazwę typu,
this
ponieważ jest ona związana w Sparta
klasie, aby wszystko było bardzo jasne.
Kod wygląda następująco:
public class Place {
public interface Athena { }
}
public class Sparta : Place
{
public void printTypeOfThis()
{
Console.WriteLine (this.GetType().Name);
}
public void printTypeOfSparta()
{
Console.WriteLine (typeof(Sparta));
}
public void printTypeOfAthena()
{
Console.WriteLine (typeof(Athena));
}
}
Teraz tworzymy Sparta
obiekt i wywołujemy trzy metody.
public static void Main(string[] args)
{
Sparta s = new Sparta();
s.printTypeOfThis();
s.printTypeOfSparta();
s.printTypeOfAthena();
}
}
Wynik, jaki otrzymujemy, to:
Sparta
Athena
Place+Athena
Jeśli jednak zmodyfikujemy klasę Place i zdefiniujemy interfejs Sparta:
public class Place {
public interface Athena { }
public interface Sparta { }
}
to właśnie ten Sparta
- interfejs - będzie dostępny jako pierwszy dla mechanizmu wyszukiwania nazw, a wynik naszego kodu zmieni się na:
Sparta
Place+Sparta
Place+Athena
Tak więc skutecznie pomieszaliśmy porównanie typów w MakeItReturnFalse
definicji funkcji, po prostu definiując interfejs Sparty w nadklasie, który znajduje się jako pierwszy na podstawie rozpoznawania nazw.
Ale dlaczego C # wybrał priorytetyzację interfejsów zdefiniowanych w nadklasie w rozpoznawaniu nazw? @JonSkeet wie! A jeśli przeczytasz jego odpowiedź, zobaczysz szczegóły protokołu rozpoznawania nazw w C #.