С#: проверка аргумента: пустые/пустые строки
Я не знаю, сколько раз мне приходилось писать код для проверки строковых аргументов:
public RoomName(string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException("Cannot be empty", "name");
}
}
Во всяком случае, чтобы избежать этого? Есть ли какой-то атрибут или механизм дизайна за контрактом, чтобы избежать этого? Невозможно сказать:
public RoomName(NotNullOrEmptyString name)
{
без фактического создания этого типа?
Ответы
Ответ 1
Вы можете сделать это с помощью ввода кода с атрибутами.
Другой вариант сохранения некоторого времени кодирования, но все же даст вам большой контроль, будет использовать что-то вроде CuttingEdge.Conditions. Это обеспечивает свободный интерфейс для проверки аргументов, поэтому вы можете написать:
name.Requires().IsNotNull();
Ответ 2
Хотя вопрос был дан некоторое время назад, я думал о той же проблеме в последнее время. Формализованные кодовые контракты (с автоматической проверкой или проверкой) кажутся хорошей идеей, но, как правило, их возможности проверки довольно ограничены, и для простых проверок, таких как проверка нулевой или пустой строки, требуется столько же кода (или более), чем старомодные проверки.
По иронии судьбы, лучший ответ, на мой взгляд, на строковый регистр - это действительно один или два класса, которые обертывают строку, которая была проверена, чтобы она не была пустой, пустой или белой пробелами и передала этот экземпляр вокруг:
public class NonEmptyString : IComparable<NonEmptyString>, ...
{
private readonly string _value;
public NonEmptyString(string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (value.Length == 0)
{
throw NewStringIsEmptyException("value");
}
_value = value;
}
public string Value
{
get { return _value; }
}
...
}
public class NonWhiteSpaceString : NonEmptyString
{
....
}
Конечно, обход этих экземпляров не мешает вам проверять, являются ли они нулевыми, но он получил некоторые большие преимущества:
- Вам не нужно снова и снова проверять пустые или белые пробелы, которые могут быть подвержены ошибкам в ситуациях, когда строка передается вокруг много.
- Как я уже делал в своей реализации, проверка на null - это нечто иное, чем проверка на пустое значение (или значение пробела), потому что вы хотите бросить определенное исключение ArgumentNullException в первом случае и некоторое исключение ArgumentException во втором.
- Он четко сигнализирует ограничение на значение строки, как и любой класс упаковки. На самом деле, если у вас есть строка, которая имеет какие-либо ограничения, и она передается по многим параметрам, я всегда рекомендую ее обернуть в класс, который инкапсулирует проверку и оставит остальную часть кода вне проблем. Хорошим примером этого являются строки, которые должны удовлетворять определенному регулярному выражению. Однако я отвлекаюсь от вопроса здесь...
Ответ 3
См. также С#: как реализовать и использовать атрибут NotNull и CanBeNull для получения дополнительной информации о кодовых контрактах, как они могут быть реализованы сегодня в VS2008 и как они будет интегрирована в VS2010.