Подтвердить что ты не робот

Что означает Эрик Липпер, "вам нужно знать, что базовый класс должен определить, что такое базовый класс"?

Я просто прочитал эту интересную статью Эрика Липперта, Топ-10 худших функций С#. Ближе к концу он утверждает:

Правила для разрешения имен после вышеупомянутого двоеточия не являются хорошо обоснованный; вы можете оказаться в ситуациях, когда вам нужно знать, что базовый класс должен определить, что такое базовый класс.

По двоеточию он ссылается на оператор наследования (например, Dog : Animal).

В какой ситуации относится Эрик? Может ли кто-нибудь предоставить образец кода?

4b9b3361

Ответ 1

Это может произойти в свернутых сценариях с дженериками, наследованием и вложенными классами:

class Base<T> {
    public class Inner {}
}

class Derived : Base<Derived.Inner2> {
    public class Inner2 : Inner {}
}

Результат

  • Чтобы определить базовый класс Derived, нам нужно привязать Derived.Inner2.
  • Чтобы связать Derived.Inner2, нам нужно разрешить символ Inner.
  • Символ Inner наследуется от его содержащего базовый класс видимости, поэтому нам нужно снова определить базовый класс Derived.

Ответ 2

SLaks дает хороший ответ; см. мои комментарии для некоторых дополнительных заметок.

Как я уже сказал в комментариях, я ищу свои старые заметки по этому вопросу, и если я их найду, я напишу блог. Здесь интересный дополнительный пример. Эта программа является законной. Являются ли значения N в декларации класса и полевые декларации одинаковыми или разными? Если они одинаковы, что для них является полностью квалифицированным типом? Если они разные, почему спецификация требует, чтобы они были разными?

public class N {}
public class B<T> 
{
    public class N {}
}

public class D : B<N> // base class
{
  N n;  // field
}

Это иллюстрирует основную проблему: поиск имени требует, чтобы базовый класс был известен, но базовый класс просматривается по имени.

Теперь подумайте о том, как интерфейсы работают в миксе. Предположим, что класс D также реализует интерфейс IN, аналогично вложенный в B и доступный глобально. Определяет ли интерфейс поиск базового класса или глобального пространства имен? Это те вопросы, которые вы должны решить, когда пишете компилятор.