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

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

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

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

Ответы [ 6 ]

6 голосов
/ 06 октября 2010

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

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

6 голосов
/ 06 октября 2010

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

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

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

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

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

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

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. 
    }
}
1 голос
/ 07 октября 2010

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

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

0 голосов
/ 06 января 2011

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

0 голосов
/ 07 октября 2010

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

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

0 голосов
/ 06 октября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...