Защищенный внутренний C# означает защищенный *ИЛИ* внутренний. Означает ли какое-либо ключевое слово защищенный * И * внутренний?

Мне нужно объявить элемент, который является одновременно защищенным И внутренним. Однако, к моему полному недоумению, я только что обнаружил, что «защищенный внутренний» на самом деле означает защищенный ИЛИ внутренний. Есть ли какой-либо модификатор доступа, означающий защищенный И внутренний?


person pyon    schedule 08.04.2011    source источник
comment
@Роуленд Шоу: я не могу этого показать. Это собственный код. О, а также, вы не хотите видеть огромный беспорядок метапрограммирования, который я создаю.   -  person pyon    schedule 08.04.2011
comment
Обычно одного internal было бы достаточно, если только по какой-либо причине вы не разрешаете случайным людям добавлять классы в вашу сборку.   -  person Powerlord    schedule 08.04.2011
comment
@Р. Бемроуз: Я знаю, я знаю. Но это эквивалентно без необходимости жертвованию объектно-ориентированной согласованностью ради компонентно-ориентированной согласованности. По сути, вы говорите что-то вроде «Кого волнует внутренняя согласованность внутреннего дизайна моей сборки, если она все равно будет черным ящиком для внешнего мира?»   -  person pyon    schedule 08.04.2011
comment
Обновлен мой ответ ниже, чтобы включить обходной путь.   -  person Chris Ammerman    schedule 08.04.2011
comment
Это может вас смутить: blogs.msdn.com/b/ericlippert/archive/2008/04/24/   -  person Eric Lippert    schedule 08.04.2011
comment
@Eric: Я едва ли не сбит с толку. Как некоторые люди ответили на ваш пост, protected и internal намного полезнее, чем protected или internal, которые приятны, но не обязательны. Я очень стараюсь и до сих пор не могу придумать реальный сценарий, в котором protected или internal является правильным модификатором доступа. (Но, в любом случае, так уж устроен C#, поэтому я воспользуюсь internal и заткнусь. Не потому, что он мне нравится, а потому, что нет ничего лучше.)   -  person pyon    schedule 08.04.2011


Ответы (5)


Хотя CLR поддерживает его, в C# нет способ заставить члена быть защищенным И внутренним.

И C#, и VB.NET объединяют модификаторы доступа, используя союз, а не пересечение.

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

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

public class AccessHelper<T>
{
    internal T Value { get; set; }
}

public class AClass
{
    public AClass()
    {
        InternalProperty.Value = "Can't get or set this unless you're a derived class inside this assembly.";
    }

    protected AccessHelper<String> InternalProperty
    {
        get;
        set;
    }
}
person Chris Ammerman    schedule 08.04.2011
comment
Тип члена, который я хочу объявить защищенным и внутренним, недоступен даже за пределами сборки. Таким образом, ваш обходной путь не работает. - person pyon; 08.04.2011
comment
Это сработает, если только не произойдет что-то еще, о чем вы не упомянули. Серьезно, попробуйте. Если это не сработает, дайте мне знать, почему. Он должен работать. В моем примере свойство InternalProperty будет видно за пределами сборки, но НЕ свойство Value этого свойства, потому что Value является внутренним. Здесь вы храните фактическое значение, которое хотите защитить, И внутреннее. - person Chris Ammerman; 08.04.2011
comment
Извините, теперь я понял, что вы предложили. Но это действительно некрасивая вещь. Тот, кто собирается поддерживать мой проект, найдет меня и зарежет до смерти. (Кроме того, мне понадобится AccessHelper<T> на класс, который должен подделывать защищенные внутренние члены.) - person pyon; 08.04.2011
comment
@Eduardo На самом деле то, что AccessHelper является внутренним классом, было ошибкой с моей стороны. Он может быть публичным. Релевантны только модификаторы доступа к свойствам. Я обновил пример кода, чтобы отразить это. Это делает вещи немного чище. Это все еще не идеально, очевидно. Но намного лучше, чем иметь внутренние классы повсюду. - person Chris Ammerman; 08.04.2011

защищенный И внутренний недоступен в С# (или любом другом языке .NET высокого уровня, если не ошибаюсь). Хотя это поддерживается CLR и может быть достигнуто в IL.

person MattDavey    schedule 08.04.2011

Цитата из ссылки Equiso:

Кстати, в CLR есть понятие ProtectedANDInternal, но в C# нет синтаксиса для его указания. Если вы посмотрите на перечисление System.Reflection.MethodAttributes CLR, вы увидите как FamANDAssem, так и FamORAssem («Семейство» — это термин CLR для защищенного C#, а «Assem» — внутренний C#).

person DaeMoohn    schedule 08.04.2011

Вы не можете определить члены защищенные И внутренние в C#, хотя это поддерживается средой CLR (MemberAttributes.FamilyAndAssembly)

person Thomas Levesque    schedule 08.04.2011

Как насчет внутреннего класса и защищенного члена.

person Lukasz Madon    schedule 08.04.2011
comment
Вы можете использовать атрибут, чтобы установить видимость для определенной .dll, но я думаю, что вы выбрали неправильный шаблон. Вместо наследования используйте составной шаблон или посетитель. - person Lukasz Madon; 08.04.2011