Рекомендации по ограничению доступа к параметру 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 - это, на мой взгляд, гораздо больше интуитивно понятно, что фильтр каким-то образом применяется, форма или форма к Класс папки. В самом деле, еще один класс может быть добавлен в пространство имен с его собственная концепция фильтра, одним из членов которой может быть "Файл". Просто потому что вы ввели новый класс в пространство имен, это не дает вы имеете право загрязнить это пространство имен различными типами "помощников". Если вы развиваетесь как часть большой команды разработчиков, ваш стиль это, ну, грубо.

...

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

Ответ 3

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

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

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