Почему я не могу иметь открытый класс, который наследуется от внутреннего класса? - PullRequest
1 голос
/ 05 января 2012

Я не понимаю ограничения доступности, представленные ниже

public abstract class Base { }
internal class Common : Base { }
public class Instance : Common { }

Это не скомпилируется.

Непоследовательная доступность: базовый класс «Общий» менее доступен, чем класс «Экземпляр»

Я могу выполнить то, что хотел, с помощью публичного абстрактного класса Common, но почему я не могу просто не раскрывать имя?

Редактировать: я спрашиваю: ПОЧЕМУ это работает так! Каждый отвечает, что такое правила, а не объясняет, почему правила таковы.

Ответы [ 3 ]

3 голосов
/ 05 января 2012

Наследники класса не могут расширить область доступности базового класса.

public: доступ не ограничен внутренним: доступ ограничен этой программой

После ограничениядля программы все наследники, internal class должны оставаться internal или предполагать меньшую доступность (protected internal или private).

В соответствии со спецификацией C # , раздел §3.5.4 Ограничения доступности :

Типы параметров конструктора экземпляра должны быть как минимум такими же доступными, как и сам конструктор экземпляра.

В примере

class A {...}

public class B: A {...}

класс B приводит к ошибке времени компиляции, поскольку A по крайней мере не так доступен, как B.

Также:

Прямой базовый класс типа класса должен быть как минимум таким же доступным, как и сам тип класса (§3.5.2).Например, для общего класса ошибка времени компиляции является производной от частного или внутреннего класса.

Если вы пытаетесь создать класс Common с функциональностью, которую вы предпочитаете не делатьдоступный для внешнего кода, вы должны предпочесть композицию наследованию .Например:

public abstract class Base
{
...
}

internal class Common : Base
{
...
}

public class Instance
{
    internal Instance(Common common)
    {
        ...
    }
...
}
2 голосов
/ 05 января 2012

Вопрос в том, насколько видим код для других сборок. Делая Common внутренним, вы ограничиваете доступ к Common своей сборке, тогда как, делая Instance общедоступным, вы делаете Instance доступным для любой ссылочной сборки. Если ссылочная сборка не может получить доступ к базовому классу типа, как она может получить доступ к любым членам, унаследованным от этого базового класса?

0 голосов
/ 05 января 2012

Если Common содержит свойство, скажем Foo:

public string Foo { get; set; }

, чем класс Instance автоматически предоставит это свойство.Вы можете думать об этом следующим образом:

public void Test()
{
    Common myInstance = new Instance();
    System.Console.WriteLine(myInstance.Foo);
}

Поскольку Instance необходимо раскрыть все, что есть Common, модификатор доступа в базовом классе не может быть менее уязвимым.

Вы можетеоднако создайте свойство Foo как внутреннее, чтобы выполнить то же самое.

...