2009-03-11 3 views
47

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

Например, это C# код:

public string MyProperty 
{ 
    get 
    { 
     return _MyBackingField; 
    } 
    set 
    { 
     if (value.Length > 100) 
      throw new FooException("MyProperty has a maximum length of 100."); 

     _MyBackingField = value; 
    } 
} 

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

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

ответ

44

Посмотрите через mscorlib.dll с отражателем, в подобной ситуации, такие как Microsoft System.String.StringBuilder.Capacity использовать ArgumentOutOfRangeException(), аналогичный:

public int PropertyA 
{ 
    get 
    { 
     return //etc... 
    } 
    set 
    { 
     if (condition == true) 
     { 
      throw new ArgumentOutOfRangeException("value", "/* etc... */"); 
     } 
     // ... etc 
    } 
} 
+1

Btv, Моно бросает ArgumentException в этом случае ... –

+13

«ArgumentOutOfRangeException - Исключение, которое генерируется, когда значение аргумента находится вне допустимого диапазона значений, согласно определению вызванный метод " .... imo, Mono должен исправить свой код. –

-1

Вы можете использовать InvalidOperationException. Это компромисс. Я бы тоже не стал использовать исключение ArgumentException.

16

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

10

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

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

процитировать от Microsoft Design Guidelines for Developing Class Libraries:

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

+4

Хотя я лично вообще не согласен (валидация - это задание сеттера в конце концов - иначе нет смысла иметь что-то другое, кроме простого поля = значение; поле возврата, геттеры/сеттеры - мне нравится, что вы поднимаете точку DataBinding, который действительно может вызвать вас в беспорядке. –

+1

Исключение метаморфизма в установщиках свойств - это нормально, но я бы не выбрасывал исключения из свойств getters. –

+0

Откладывание выброса исключения не позволит вам поймать искатель. если программист забудет, чтобы поймать исключение, то он прыгнет на его лицо, вместо того, чтобы пузыриться непреднамеренно. – Trap

6

Помните, сколько проблем в информатике разрешено путем добавления дополнительного уровня косвенности?

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

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

+2

Как бы вы справились с передачей FixedLengthString с максимальным количеством 100 символов в свойство, которое требовало установки FixedLengthString с максимальным количеством символов до 50 символов? –

-2

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

При метании InvalidOperationException отображается значение, переданное этому установщику.

+0

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

+2

InvalidOperationException не следует поднимать в этом случае. Неправильно значение, а не операция установки значения. – Trap

5
public IPAddress Address 
{ 
    get 
    { 
     return address; 
    } 
    set 
    { 
     if(value == null) 
     { 
      throw new ArgumentNullException("value"); 
     } 
     address = value; 
    } 
} 

с помощью MSDN

+0

Хорошая точка, хотя это характерно для нулевого случая. Тем не менее, он поддерживает использование для серии 'ArgumentException', поэтому +1 для ссылки. –

 Смежные вопросы

  • Нет связанных вопросов^_^