Я пробовал Lokad Shared Libraries, и он выглядит очень интересным и полезным. Я могу использовать, например:
Enforce.Arguments(() => arg1, () => arg2);
чтобы вызвать исключение, если arg1 или arg2 имеют значение null. Но я хотел бы проверить, имеет ли IEnumerable хотя бы один элемент. Я мог бы использовать:
Enforce.That(someSequence.Count() > 0);
но это не создает очень полезное сообщение об ошибке. Я попытался посмотреть пример кода и т.д., Чтобы узнать, как писать и использовать собственное правило. Но я просто не могу понять это!
Я зашел так далеко (или коротко... точнее...):
Lokad.Rules.Rule<T>
?Итак, чтобы подвести итог, вот что я хочу в итоге:
public static void DoStuff<T>(this IEnumerable<T> subjects)
{
Enforce.Argument(() => subjects);
// Somehow in an equally smooth way check that
// subjects contains at least one element
// Do stuff
}
Любой, кто может помочь?
Вопрос о том же вопросе в сообщение в блоге Ринат Абдуллин. Получил ответ:
Здесь простейшая реализация с использованием:
public static class EnumerableIs { public static void NotEmpty<T>(IEnumerable<T> collection, IScope scope) { if (!collection.Any()) { scope.Error("Enumerable can't be empty."); } scope.ValidateInScope(collection); } } [Test, ExpectedException(typeof(ArgumentException))] public void Test() { IEnumerable<object> t = null; Enforce.Argument(() => t, EnumerableIs.NotEmpty); } [Test, ExpectedException(typeof(ArgumentException))] public void Test2() { var t = new int[0]; Enforce.Argument(() => t, EnumerableIs.NotEmpty); } [Test, ExpectedException(typeof(ArgumentException))] public void Test3() { var t = new[] { new object(), null }; Enforce.Argument(() => t, EnumerableIs.NotEmpty); }
И это действительно работает. Методы испытаний вызывают исключения из этих сообщений:
Test1: Объект типа "IEnumerable`1" не должен быть нулевым. Имя параметра: t
Test2: Перечислимый не может быть пустым. Имя параметра: t
Test3: Объект типа "Объект" не должен быть нулевым. Имя параметра: t. 1
Не совсем уверен, где Test1 и Test3 получили свои сообщения от... как, где он проверял это в методе NotEmpty<T>
... поэтому я спросил об этом...