Какое исключение выбрасывать из установщика свойств? - PullRequest
49 голосов
/ 11 марта 2009

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

Например, этот код 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, но он не вызывается как функция для глаз потребителя - он находится справа от оператора присваивания ,

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

Ответы [ 7 ]

46 голосов
/ 11 марта 2009

Просмотрите mscorlib.dll с помощью Reflector, в похожей ситуации, например System.String.StringBuilder.Capacity. Microsoft использует ArgumentOutOfRangeException (), похожую на:

public int PropertyA
{
    get
    {
        return //etc...
    }
    set
    {
        if (condition == true)
        {
            throw new ArgumentOutOfRangeException("value", "/* etc... */");
        }
        // ... etc
    }
}
16 голосов
/ 11 марта 2009

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

10 голосов
/ 11 марта 2009

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

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

Цитировать из Руководства по проектированию Microsoft для разработки библиотек классов :

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

6 голосов
/ 11 марта 2009

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

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

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

5 голосов
/ 19 февраля 2010
public IPAddress Address
{
    get
    {
        return address;
    }
    set
    {
        if(value == null)
        {
            throw new ArgumentNullException("value");
        }
        address = value;
    }
}

через MSDN

0 голосов
/ 11 марта 2009

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

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

0 голосов
/ 11 марта 2009

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

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