Вы когда-нибудь видели дизайн с разумным использованием защищенного модификатора внутреннего доступа?

У меня нет, но я не говорю, что его нет.

Все разработчики С#, которые читают это, вероятно, знают, что защищено внутренним и когда его использовать. Мой вопрос прост: вы на самом деле когда-либо использовали его или работали над успешно разработанным проектом с использованием защищенного модификатора внутреннего доступа? Если да, пожалуйста, поделитесь своими знаниями и отправьте хороший образец, где я наконец смогу оценить умное использование этого сложного модификатора.

//Я считаю, что это не субъективно, я действительно ищу ответа; -)

Ответы

Ответ 1

Я уверен, что вы можете придумать примеры, но через пять лет разработки С# я не видел хорошего примера. Пример Джона К иллюстрирует целесообразное использование модификатора хорошо, однако я считаю, что требования, которые приводят к этой ситуации, являются проблематичными. Например, в примере Джона класс имеет "дружественный" доступ в сборке, и в целом это проблема, потому что эти классы, вероятно, "спрашивают", а не "рассказывают" (программирование не вежливое, лучше сказать, чем задавать). В каком случае у вас есть полезный расширяемый класс, который Друзья могут вызывать методом, но другие не могут?

Еще одно использование будет для тестирования доступа (IE вы хотите, чтобы он был защищен, но внутренний, чтобы ваши тесты уровня сборки могли его вызвать). Это тоже неприятная ситуация - когда вы публикуете вещи как внутренние для тестирования, я думаю, что это запах дизайна, который обычно может выполнять инъекция зависимости.

Ответ 2

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

Этот комбо-модификатор позволяет сборке полностью доверять собственному содержимому и внутреннему использованию (что не является ненормальным), а также подвергать некоторые из этих членов нормальной модели деривации наследования для других сборок.

Ни один модификатор не может это сделать.

Или рассмотрите обратные ситуации:

  • если вы используете только, а другие классы внутри одной сборки не могут получить доступ к этому члену.

  • Если вы только используете внутренние, то производные классы (в других сборках) не могут переопределить этот метод.

Assembly1.dll

// ------ Assembly file 1 .dll --------

// Allow my friends (internal) and derived classes (protected) to do this. 
public class A {
    internal protected virtual void YoBusiness() {
        //do something
    }
}


class B { // not a derived class - just composites an instance of A
    public B() {
        A a = new A();
        a.YoBusiness(); // Thanks friend for the access! 
    }
}

Assembly2.dll

// ------ Assembly file 2 .dll --------

class C : A {  // derived across assemblies
    protected override void YoBusiness() {
        // Hey thanks other guy, I can provide a new implementation. 
    }
}

Ответ 3

Все члены protected или internal увеличивают сложность, связывают и тем самым уменьшают целостность абстракций. Вы можете подумать о внедрении некоторых методов, внутренних или защищенных, но использование внутренних или защищенных полей в целом - очень плохая идея. Защищенные/внутренние поля "открывают" реализацию абстракций для широкого круга классов и очень усложняют будущие модификации.

Мне не нравятся такие слова, как " никогда" или " не", но мы определенно должны использовать по крайней мере " избегать strong > " в качестве общей директивы дизайна.

Ответ 4

Вы на самом деле когда-либо использовали его

Да, наряду с InternalsVisibleTo для модульного тестирования.

Ответ 5

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

Серьезно, однако, вопрос относится только к внутренним... мы знаем, почему вы будете использовать защищенные, не так ли? Итак, почему внутреннее? Вероятно, только когда вы знаете, что ваш тип обращается к некоторым ресурсам, доступным только в одной сборке. Является ли это фактическим ресурсом или другим типом, который вы не хотите делиться с миром.

Ответ 6

Мне действительно пришлось использовать его впервые в моей карьере сегодня! У меня есть плагиновую архитектуру с baseclases, и плагины отображаются только через класс фасада. Единственный способ ограничить плагин вызываемым только через faqade - сделать его защищенным внутренним, поскольку плагины, которые его переопределяют, находятся в других сборках, в то время как слой faqade находится в том же самом, что и базовый класс

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