Подтвердить что ты не робот

Рекомендации по ограничению доступа к параметру enum в С#

Рассмотрите вопрос об этой String.Split перегрузке, которая берет StringSplitOptions перечисление как параметр.

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

Возможно, есть лучший способ моделировать это, например, поместить enum внутри самого класса String и получить к нему доступ, например, с помощью String.SplitOptions? Я очень редко вижу это (я на самом деле не могу вспомнить ни одного такого случая сейчас), поэтому я предполагаю, что он почему-то не является предпочтительным. В общем, я думаю, что сокращение объема вещей является лучшей практикой, потому что вы уменьшаете вероятность проблем, возникающих при использовании класса/члена в некорректной области, так сказать.

В качестве примера я использую Split, но довольно часто для Enum используется только метод или класс в нашей базе кода. Обычно я создаю enum как открытый тип в отдельном файле cs, как и любой другой класс, но мне бы хотелось услышать другие подходы к этой "проблеме".

Update:

Я только что нашел эту статью, которая атакует эту точную проблему, с классом Folder и Filter перечислением, но опять же кажется, что это противоречит тому, что я считаю более корректным в этом случае (размещение enum внутри класса каким-то образом). В одном из комментариев от ToddM (с которым я согласен) говорится:

...

Но даже тогда я чувствую, что ваша логика ошибочна. Ваша основная жалоба против встраивания enum внутри класса в том, что он будет слишком длинный для ввода. Учитывая, насколько велик С#, на самом деле это не так разумный аргумент. В VS, CTRL + SPACE - ваш друг.

Логически, я чувствую, что размещение enum внутри класса намного больше верный. Возьмем ваш пример: что такое MyNameSpace.Filter? Где же это применимо? Я думаю, это фильтр для вашего пространства имен? Это невозможно скажите, особенно если ваше пространство имен растет, чтобы содержать десятки классов.

Теперь рассмотрим MyNameSpace.Folder.Filter - это, на мой взгляд, гораздо больше интуитивно понятно, что фильтр каким-то образом применяется, форма или форма к Класс папки. В самом деле, еще один класс может быть добавлен в пространство имен с его собственная концепция фильтра, одним из членов которой может быть "Файл". Просто потому что вы ввели новый класс в пространство имен, это не дает вы имеете право загрязнить это пространство имен различными типами "помощников". Если вы развиваетесь как часть большой команды разработчиков, ваш стиль это, ну, грубо.

...

4b9b3361

Ответ 1

Интересная идея - вставить enum, чтобы предположить, что она имеет уменьшенную область видимости или дает ей лучшую семантику. Я использовал эту идею раньше, чтобы иметь как коды ошибок, так и коды предупреждений в посткомпиляторе Я разработал. Таким образом, я мог бы использовать то же имя перечисления Code, вложенное либо в класс Error, либо Warning class.

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

НЕ использовать общедоступные вложенные типы как конструкцию логической группировки; используйте пространства имен для этого.

ИЗБЕГАЙТЕ публично открытые вложенные типы. Единственным исключением является то, что переменные вложенного типа должны быть объявлены только в редких сценариях, таких как подклассы или другие расширенные сценарии настройки.

НЕ используйте вложенные типы, если тип, вероятно, будет ссылаться вне содержащего типа.

Например, перечисление, переданное методу, определенному в классе, не должно быть определено как вложенный тип в классе.

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

Ответ 2

String.Split() является общедоступным, поэтому StringSplitOptions должен быть общедоступным. Оба String и StringSplitOptions существуют в пространстве имен System. Оба имеют общий охват. Ни один из них не "доступен за пределами [других] областей".

Ответ 3

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

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

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