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

Я читаю книгу" C# 4.0 в двух словах " Джозефа Албабари и Бен Албабари. Оттуда я нахожу тему ограничения на модификаторы доступа. Страница 91, раздел "ограничения модификаторов доступа".

цитата из книги.

компилятор предотвращает непоследовательное использование модификаторов доступа. Для например, сам подкласс может быть менее доступен, чем базовый класс, но не больше!--5-->

Итак, это говорит о том, что базовый класс должен быть одинаково или более доступно, чем подкласс. Поэтому, если базовый класс является внутренним, подкласс должен быть либо частным, либо внутренним. Если базовый класс является частным, а подкласс-открытым, то будет создана Ошибка времени компиляции. При попытке этого в Visual Studio я обнаружил некоторое странное поведение.

попробуйте 1: база является частной и подкласс является частным (работает, правильное поведение) это также работает, если оба являются внутренними, публичными.

private class A { }
private class B : A { }         // Works

попробуйте 2: База является частной, а подкласс-публичным или внутренний (это не удается, правильное поведение)

private class A { }
public class B : A { }          // Error

Try 3: Base является внутренним, а sub-публичным (это работает, но он должен потерпеть неудачу. Поскольку база менее доступна, чем подкласс

internal class A { }
public class B : A { }          // Works, but why

теперь мой вопрос: почему попытка 3 не удалась? Подклассов и более доступным, чем базовый класс, который является внутренним. Даже в книге сказано, что это должно провалиться. Но Visual Studio успешно скомпилировал это. Это должно сработать или нет?

Edit:

Я создал новый консольный проект в VS. В Программе.cs я добавил свой код. Вот полный код программы.cs файл.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication
{
    class Program
    {
        internal class A { }
        public class B : A { }          // Error

        static void Main()
        {
        }
    }
}

1 ответов


вы размещаете вложенные классы внутри другое internal класса.

например, дано:

class Program
{
    static void Main(string[] args)
    {
    }

    internal class A { }
    public class B : A { }
}

это будет компиляции, потому что internal модификатор класса упаковки делает public модификатор на class B спорный. Скорее, введите Bдоступность ограничена своим обернутым классом Program -- его домен доступности -internal Как хорошо.

если вы обновите его до быть:

class Program
{
    static void Main(string[] args)
    {
    }
}

internal class A { }
public class B : A { }

это вызовет несогласованную ошибку компилятора видимости. Или если вы переопределите Program на public вместо internal Он также выдаст ошибку. В этом случае Bтеперь домен доступности public и больше не ограничивается Program ' s internal домен доступности.


из спецификации C#3.5.2 Домены Доступность:

домен специальных возможностей вложенного члена M объявлено в типе T в рамках программы P определяется следующим образом (отмечая, что сам M может возможно, будет тип):

если объявленная доступность M является общедоступной, домен доступности M является доменом доступности T.

и описание MSDN доступности домена:

если элемент вложен в другой тип, домена доступности определяется как уровнем доступности член и домен специальных возможностей непосредственно содержащего типа.

если тип упаковки Program is internal, затем вложенный тип B будучи public будет иметь свою доступность, чтобы соответствовать Program, таким образом, рассматриваться как internal и ошибка компилятора не возникает.