Прекрасный вопрос! Я хотел бы добавить немного более подробное объяснение для тех, кто не занимается C # каждый день ... потому что этот вопрос является хорошим напоминанием о проблемах с разрешением имен в целом.
Возьмите исходный код, немного измененный следующим образом:
- Давайте распечатаем имена типов вместо того, чтобы сравнивать их, как в исходном выражении (т.е.
return this is Sparta
).
- Давайте определим интерфейс
Athena
в Place
суперклассе, чтобы проиллюстрировать разрешение имени интерфейса.
- Давайте также распечатаем имя типа
this
, связанное с Sparta
классом, чтобы все было очень понятно.
Код выглядит так:
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));
}
}
Теперь мы создаем Sparta
объект и вызываем три метода.
public static void Main(string[] args)
{
Sparta s = new Sparta();
s.printTypeOfThis();
s.printTypeOfSparta();
s.printTypeOfAthena();
}
}
Результат, который мы получаем:
Sparta
Athena
Place+Athena
Однако, если мы изменим класс Place и определим интерфейс Sparta:
public class Place {
public interface Athena { }
public interface Sparta { }
}
тогда именно этот Sparta
интерфейс будет доступен в первую очередь механизму поиска имени, и вывод нашего кода изменится на:
Sparta
Place+Sparta
Place+Athena
Таким образом, мы фактически испортили сравнение типов в MakeItReturnFalse
определении функции, просто определив интерфейс Sparta в суперклассе, который сначала находится по разрешению имен.
Но почему C # выбрал приоритет интерфейсов, определенных в суперклассе, в разрешении имен? @JonSkeet знает! И если вы прочитаете его ответ, вы получите подробную информацию о протоколе разрешения имен в C #.