Должен ли я использовать внутреннюю или публичную видимость по умолчанию?


Я довольно новый разработчик C# и .Net. Недавно я создал MMC snapin с использованием C# и был удовлетворен тем, как легко это было сделать, особенно после того, как услышал много ужасных историй от некоторых других разработчиков в моей организации о том, как трудно это сделать в C++.

В какой-то момент я в значительной степени прошелся по всему проекту и сделал каждый экземпляр ключевого слова "public" "внутренним", за исключением случаев, когда это требуется средой выполнения для запуска snapin. Каковы ваши чувства по этому поводу, должны ли вы как правило, делают классы и методы общедоступными или внутренними?

14   40   2008-09-20 07:21:55

14 ответов:

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

Для этого дайте мне только ту функциональность, которую класс должен предоставить для работы.

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

То, что вы сделали, - это именно то, что вы должны сделать; дайте вашим классам самую минимальную видимость, которую вы можете. Черт возьми, если вы действительно хотите стать целым Боровом, вы можете сделать все internal (самое большее) и использовать InternalsVisibleTo атрибут , так что вы можете отделить свою функциональность, но все же не подвергать ее воздействию неизвестного внешнего мира.

Единственная причина, чтобы сделать вещи открытыми, заключается в том, что вы упаковываете свой проект в несколько библиотек DLL и / или EXEs, и (по какой-либо причине) вы не хотите использовать InternalsVisibleTo, или вы создаете библиотеку для использования третьими лицами. Но даже в библиотеке, предназначенной для использования третьими лицами, вы должны стараться по возможности уменьшить "площадь поверхности"; чем больше классов вы имеете в наличии, тем более запутанной будет ваша библиотека.

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

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

Вы должны быть осторожны, но не скрывать полезную функциональность от ваших пользователей. В .NET BCL есть много полезных методов, которые нельзя использовать, не прибегая к рефлексии. Однако, скрывая эти методы площадь поверхности того, что должно быть проверено и поддерживаемое уменьшается.

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

Вместо того, чтобы помечать класс как internal, я оставляю доступность пустой. Таким образом, public выделяется для глаза как нечто заметное. (Исключение, конечно, составляют вложенные классы, которые должны быть помечены, если они должны быть видны даже в одной сборке.)

Большинство классов должно быть internal, но большинство неприватизированных членов должно быть public.

Вопрос, который вы должны задать о члене: "если бы класс был сделан public, я бы хотел, чтобы член был открыт?". Ответ обычно "да (so public)", потому что классы без каких-либо доступных членов не очень полезны! internal у членов есть роль; они являются "черным ходом", предназначенным только для близких родственников, которые живут в том же собрании.

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

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

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

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

Я нашел задачу , используя внутренние классы настолько, насколько это возможно. Вы не можете иметь методы, свойства, поля и т. д. этого типа (или типа параметра или возвращаемого типа) более видимыми, чем внутренние. Это приводит к тому, что конструкторы являются внутренними, а также свойствами. Это не должно быть проблемой, но на самом деле при использовании Visual Studio и конструктора xaml возникают проблемы. ложноположительные ошибки обнаруживаются проектировщиком в связи с тем, что методы не общедоступные, свойства пользовательского элемента управления, по-видимому, не видны разработчику. Не знаю, попадались ли уже другие на такие темы...

Вы должны постараться сделать их как можно более видимыми, но, как указано Майком выше, это вызывает проблемы с UserControls и использованием VS Designer с этими элементами управления на формах или других UserControls.

Поэтому, как правило, все классы и UserControls, которые вы не добавляете с помощью конструктора, должны быть видны только так, как это необходимо. Если вы создаете UserControl, который хотите использовать в конструкторе (даже если он находится в той же сборке), вам нужно будет убедиться, что что класс UserControl, его конструктор по умолчанию и любые свойства, а также события становятся общедоступными для конструктора для работы с ним.

Недавно у меня была проблема, когда дизайнер продолжал удалять это.myControl = новая строка MyControl() из метода InitializeComponent (), так как UserControl MyControl был помечен как внутренний вместе с его конструктором.

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

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

Не выбирайте" по умолчанию " выберите то, что лучше всего соответствует потребностям видимости для этого конкретного класса. При выборе нового класса в Visual Studio шаблон создается следующим образом:

class Class1
{
}

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

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

Я буду поднимать что-то видимое вверх по этой цепи к публике только тогда, когда есть хорошая причина.

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

Сегодня мне пришлось использовать рефлексию, чтобы добраться до внутренних органов системы.Данные.DataTable (я должен построить datatable молниеносно, без всех его проверок), и я должен был использовать отражение, так как мне не был доступен ни один тип; все они были помечены как внутренний.

По умолчанию класс создается как внутренний в c#: внутренние средства: доступ ограничен к текущей сборке.

См. http://msdn.microsoft.com/en-us/library/0b0thckt.aspx

Хорошая статья область по умолчанию-внутренняя: http://www.c-sharpcorner.com/UploadFile/84c85b/default-scope-of-a-C-Sharp-class/