dotnet add package throw

喜欢它吗?通过给这个项目一个星标来表示你的支持!
这个库设计时考虑了启用可空引用类型特性的情况。
Throw() 方法是所有非空类型的入口方法:
string name = "hello"; name.Throw().IfLongerThan(10);
而 ThrowIfNull() 用于任何可空类型:
string? name = "hello"; name.ThrowIfNull();
尝试在可空类型上使用 Throw() 将会给出警告
string? name = null; name.Throw() // 警告 CS8714:类型"string?"不能用作泛型类型或方法"ValidatableCreationExtensions.Throw<TValue>(TValue, ExceptionCustomizations?, string?)"中的类型参数"TValue"。类型参数"string?"的可空性与"notnull"约束不匹配。 .IfEmpty();
在验证可空类型不为 null 后,可以使用所有常规的非空规则
name.ThrowIfNull() .IfEmpty() .IfLongerThan(3);
表达式可以隐式转换为原始可空类型的非空类型
string? name = "Amichai"; string nonNullableName = name.ThrowIfNull() .IfEmpty() .IfLongerThan(10);
或者
int? a = 5; int b = a.ThrowIfNull();
如果你已经自 定义了异常,任何抛出异常的规则都将使用该自定义。例如:
// 默认行为: name.Throw() .IfEmpty() // System.ArgumentException:字符串不应为空。(参数"name") .IfWhiteSpace() // System.ArgumentException:字符串不应仅包含空白字符。(参数"name") .IfLongerThan(3) // System.ArgumentException:字符串长度不应超过 3 个字符。(参数"name") .IfShorterThan(10); // System.ArgumentException:字符串长度不应少于 10 个字符。(参数"name") // 自定义行为: name.Throw(paramName => throw new MyCustomException($"参数名称:{paramName}。")) .IfEmpty() // MyCustomException:参数名称:name。 .IfWhiteSpace() // MyCustomException:参数名称:name。 .IfLongerThan(3) // MyCustomException: 参数名称:name。 .IfShorterThan(10); // MyCustomException:参数名称:name。
你可以随时更改异常自定义,它将应用于之后的所有规则。例如:
name.Throw("字符串不应为空或仅包含空白字符。") .IfEmpty() // System.ArgumentException:字符串不应为空或仅包含空白字符。(参数"name") .IfWhiteSpace() // System.ArgumentException:字符串不应为空或仅包含空白字符。(参数"name") .Throw("字符串长度不应在 3 到 10 个字符之间。") .IfLongerThan(3) // System.ArgumentException:字符串长度不应在 3 到 10 个字符之间。(参数"name") .IfShorterThan(10); // System.ArgumentException:字符串长度不应在 3 到 10 个字符之间。(参数"name")
要返回默认异常,只需使用 Throw() 方法。例如:
name.Throw("字符串不应为空或仅包含空白字符。") .IfEmpty() // System.ArgumentException:字符串不应为空或仅包含空白字符。(参数"name") .IfWhiteSpace() // System.ArgumentException:字符串不应为空或仅包含空白字符。(参数"name") .Throw() .IfLongerThan(3) // System.ArgumentException:字符串长度不应超过 3 个字符。(参数"name") .IfShorterThan(10); // System.ArgumentException:字符串长度不应少于 10 个字符。(参数"name")
Throw()每个规则都有默认行为。如果你不自定义异常,将使用默认行为。
使用 Throw() 或 ThrowIfNull() 方法抛出默认异常
// ArgumentNullException:值不能为 null。(参数"nullableValue") nullableValue.ThrowIfNull(); // System.ArgumentOutOfRangeException:值不应小于 2042/2/28 16:41:46。(参数"dateTime")\n 实际值为 2022/2/28 16:41:46。 dateTime.Throw().IfLessThan(DateTime.Now.AddYears(20)); // ArgumentException:值不应为 true(参数"isGood") isGood.Throw().IfTrue(); // System.ArgumentException :字符串不应为空。(参数"name") name.Throw().IfEmpty(); // System.ArgumentOutOfRangeException:值不应大于 0。(参数"number")\n 实际值为 5。 number.Throw().IfPositive();
Throw("我的自定义消息")向 Throw() 或 ThrowIfNull() 方法传递自定义异常消息
// System.ArgumentNullException:我的自定义消息(参数"nullableValue") nullableValue.ThrowIfNull("我的自定义消息"); // System.ArgumentOutOfRangeException:我的自定义消息(参数"dateTime")\n 实际值为 2022/3/1 10:47:15。 dateTime.Throw("我的自定义消息").IfLessThan(DateTime.Now.AddYears(20)); // System.ArgumentException:我的自定义消息(参数"isGood") isGood.Throw("我的自定义消息").IfTrue(); // System.ArgumentException:我的自定义消息(参数"name") name.Throw("我的自定义消息").IfEmpty(); // System.ArgumentOutOfRangeException:我的自定义消息(参数"number")\n 实际值为 5。 number.Throw("我的自定义消息").IfPositive();
Throw(() => new MyException())向 Throw() 或 ThrowIfNull() 方法传递自定义异常抛出器
// MyCustomException:抛出了"MyCustomException"类型的异常。 nullableValue.ThrowIfNull(() => throw new MyCustomException()); // MyCustomException:抛出了"MyCustomException"类型的异常。 dateTime.Throw(() => throw new MyCustomException()).IfLessThan(DateTime.Now.AddYears(20)); // MyCustomException:抛出了"MyCustomException"类型的异常。 isGood.Throw(() => throw new MyCustomException()).IfTrue(); // MyCustomException:抛出了"MyCustomException"类型的异常。 name.Throw(() => throw new MyCustomException()).IfEmpty(); // MyCustomException:抛出了"MyCustomException"类型的异常。 number.Throw(() => throw new MyCustomException()).IfPositive();
Throw(paramName => new MyException($"参数:{paramName}")向 Throw() 或 ThrowIfNull() 方法传递一个自定义异常抛出器,该抛出器接受参数名称作为参数
这在以下场景中很有用:
void SendEmail(User user) { user.Throw(paramName => new UserException(message: "由于用户详细信息无效,无法发送电子邮件。", paramName: paramName)) .IfWhiteSpace(user => user.FirstName) // UserException: 由于用户详细信息无效,无法发送电子邮件。 (参数 'user: user => user.FirstName') .IfWhiteSpace(user => user.LastName) // UserException: 由于用户详细信息无效,无法发送电子邮件。 (参数 'user: user => user.LastName') .IfNull(user => user.Email) // UserException: 由于用户详细信息无效,无法发送电子邮件。 (参数 'user: user => user.Email') .IfLongerThan(user => user.Email!, 100); // UserException: 由于用户详细信息无效,无法发送电子邮件。 (参数 'user: user => user.Email!') emailService.TrySendEmail(user) .Throw(() => new EmailException("无法发送电子邮件。")) .IfFalse(); }
// MyCustomException: 参数名称: nullableValue. nullableValue.ThrowIfNull(paramName => throw new MyCustomException($"参数名称: {paramName}.")); // MyCustomException: 参数名称: dateTime. dateTime.Throw(paramName => throw new MyCustomException($"参数名称: {paramName}.")).IfLessThan(DateTime.Now.AddYears(20)); // MyCustomException: 参数名称: isGood. isGood.Throw(paramName => throw new MyCustomException($"参数名称: {paramName}.")).IfTrue(); // MyCustomException: 参数名称: name. name.Throw(paramName => throw new MyCustomException($"参数名称: {paramName}.")).IfEmpty(); // MyCustomException: 参数名称: number. number.Throw(paramName => throw new MyCustomException($"参数名称: {paramName}.")).IfPositive();
value.Throw().IfTrue(); // ArgumentException: 值不应为true (参数 'value') value.Throw().IfFalse(); // ArgumentException: 值应为true (参数 'value') // 任何返回布尔值的方法都可以内联其异常抛出逻辑。 Enum.TryParse("意外值", out EmployeeType value) .Throw() .IfFalse(); // System.ArgumentException: 值应为true。 (参数 'Enum.TryParse("意外值", out EmployeeType value)')
bool?, int?, double?, DateTime? 等)bool? value = null; value.ThrowIfNull(); // ArgumentNullException: 值不能为null。 (参数 'value') // 在验证 `ThrowIfNull` 后,可以使用任何常规值类型扩展。 value.ThrowIfNull() // ArgumentNullException: 值不能为null。 (参数 'value') .IfTrue(); // ArgumentException: 值不应为true (参数 'value') // `ThrowIfNull` 返回的值可以隐式转换为原始的非可空类型。 bool nonNullableValue = value.ThrowIfNull(); // ArgumentNullException: 值不能为null。 (参数 'value')
name.Throw().IfEmpty(); // System.ArgumentException: 字符串不应为空。 (参数 'name') name.Throw().IfWhiteSpace(); // System.ArgumentException: 字符串不应只包含空白字符。 (参数 'name') name.Throw().IfLengthEquals(7); // System.ArgumentException: 字符串长度不应等于7。 (参数 'name') name.Throw().IfLengthNotEquals(10); // System.ArgumentException: 字符串长度应等于10。 (参数 'name') name.Throw().IfShorterThan(10); // System.ArgumentException: 字符串长度不应短于10个字符。 (参数 'name') name.Throw().IfLongerThan(3); // System.ArgumentException: 字符串长度不应超过3个字符。 (参数 'name') name.Throw().IfEquals("Amichai"); // System.ArgumentException: 字符串不应等于 'Amichai' (比较类型: 'Ordinal')。 (参数 'name') name.Throw().IfEquals("Amichai", StringComparison.InvariantCulture); // System.ArgumentException: 字符串不应等于 'Amichai' (比较类型: 'InvariantCulture')。 (参数 'name') name.Throw().IfEqualsIgnoreCase("AMICHAI"); // System.ArgumentException: 字符串不应等于 'AMICHAI' (比较类型: 'OrdinalIgnoreCase')。 (参数 'name') name.Throw().IfNotEquals("Dan"); // System.ArgumentException: 字符串应等于 'Dan' (比较类型: 'Ordinal')。 (参数 'name') name.Throw().IfNotEquals("Dan", StringComparison.InvariantCultureIgnoreCase); // System.ArgumentException: 字符串应等于 'Dan' (比较类型: 'InvariantCultureIgnoreCase')。 (参数 'name') name.Throw().IfNotEqualsIgnoreCase("Dan"); // System.ArgumentException: 字符串应等于 'Dan' (比较类型: 'OrdinalIgnoreCase')。 (参数 'name') name.Throw().IfContains("substring"); // System.ArgumentException: 字符串不应包含 'substring' (比较类型: 'Ordinal')。 (参数 'name') name.Throw().IfContains("substring", ComparisonType.InvariantCulture); // System.ArgumentException: 字符串应包含 'substring' (比较类型: 'InvariantCulture')。 (参数 'name') name.Throw().IfNotContains("substring"); // System.ArgumentException: 字符串应包含 'substring' (比较类型: 'Ordinal')。 (参数 'name') name.Throw().IfNotContains("substring", ComparisonType.InvariantCultureIgnoreCase); // System.ArgumentException: 字符串应包含 'substring' (比较类型: 'InvariantCultureIgnoreCase')。 (参数 'name') name.Throw().IfStartsWith("Jer"); // System.ArgumentException: 字符串不应以 'Jer' 开头 (比较类型: 'Ordinal')。 (参数 'name') name.Throw().IfStartsWith("JER", StringComparison.OrdinalIgnoreCase); // System.ArgumentException: 字符串不应以 'JER' 开头 (比较类型: 'OrdinalIgnoreCase')。 (参数 'name') name.Throw().IfNotStartsWith("dan"); // System.ArgumentException: 字符串应以 'dan' 开头 (比较类型: 'Ordinal')。 (参数 'name') name.Throw().IfNotStartsWith("dan", StringComparison.InvariantCultureIgnoreCase); // System.ArgumentException: 字符串应以 'dan' 开头 (比较类型: 'InvariantCultureIgnoreCase')。 (参数 'name') name.Throw().IfEndsWith("emy"); // System.ArgumentException: 字符串不应以 'emy' 结尾 (比较类型: 'Ordinal')。 (参数 'name') name.Throw().IfEndsWith("EMY", StringComparison.OrdinalIgnoreCase); // System.ArgumentException: 字符串不应以 'EMY' 结尾 (比较类型: 'OrdinalIgnoreCase')。 (参数 'name') name.Throw().IfNotEndsWith("dan"); // System.ArgumentException: 字符串应以 'dan' 结尾 (比较类型: 'Ordinal')。 (参数 'name') name.Throw().IfNotEndsWith("dan", StringComparison.OrdinalIgnoreCase); // System.ArgumentException: 字符串应以 'dan' 结尾 (比较类型: 'OrdinalIgnoreCase')。 (参数 'name') name.Throw().IfMatches("J.*y"); // System.ArgumentException: 字符串不应匹配正则表达式模式 'J.*y' (参数 'name') name.Throw().IfMatches("[a-z]{0,10}", RegexOptions.IgnoreCase); // System.ArgumentException: 字符串不应匹配正则表达式模式 '[a-z]{0,10}' (参数 'name') name.Throw().IfNotMatches("^[0-9]+$"); // System.ArgumentException: 字符串应匹配正则表达式模式 '^[0-9]+$' (参数 'name') name.Throw().IfNotMatches("abc ", RegexOptions.IgnorePatternWhitespace); // System.ArgumentException: 字符串应匹配正则表达式模式 '^[0-9]+$' (参数 'name')
IEnumerable, IEnumerable<T>, ICollection, ICollection<T>, IList, 等)重要提示:如果集合是未求值的表达式,该表达式将被求值。
collection.Throw().IfHasNullElements(); // System.ArgumentException: 集合不应包含空元素。 (参数 'collection') collection.Throw().IfEmpty(); // System.ArgumentException: 集合不应为空。 (参数 'collection') collection.Throw().IfNotEmpty(); // System.ArgumentException: 集合应为空。 (参数 'collection') collection.Throw().IfCountLessThan(5); // System.ArgumentException: 集合计数不应小于5。 (参数 'collection') collection.Throw().IfCountGreaterThan(1); // System.ArgumentException: 集合计数不应大于1。 (参数 'collection') collection.Throw().IfCountEquals(0); // System.ArgumentException: 集合计数不应等于0。 (参数 'collection') collection.Throw().IfCountNotEquals(0); // System.ArgumentException: 集合计数应等于0。 (参数 'collection') collection.Throw().IfContains("value"); // System.ArgumentException: 集合不应包含元素。 (参数 'person: p => p.Friends') collection.Throw().IfNotContains("value"); // System.ArgumentException: 集合应包含元素。 (参数 'person: p => p.Friends')
dateTime.Throw().IfUtc(); // System.ArgumentException: 值不应为Utc。 (参数 'dateTime') dateTime.Throw().IfNotUtc(); // System.ArgumentException: 值应为Utc。 (参数 'dateTime') dateTime.Throw().IfDateTimeKind(DateTimeKind.Unspecified); // System.ArgumentException: 值不应为Unspecified。 (参数 'dateTime') dateTime.Throw().IfDateTimeKindNot(DateTimeKind.Local); // System.ArgumentException: 值应为Local。 (参数 'dateTime') dateTime.Throw().IfGreaterThan(DateTime.Now.AddYears(-20)); // System.ArgumentOutOfRangeException: 值不应大于 2002/2/28 16:41:19。 (参数 'dateTime') dateTime.Throw().IfLessThan(DateTime.Now.AddYears(20)); // System.ArgumentOutOfRangeException: 值不应小于 2042/2/28 16:41:46。 (参数 'dateTime') dateTime.Throw().IfEquals(other); // System.ArgumentException: 值不应等于 2022/2/28 16:44:39。 (参数 'dateTime')
employeeType.Throw().IfOutOfRange(); // System.ArgumentOutOfRangeException: 值应在枚举中定义。 (参数 'employeeType') employeeType.Throw().IfEquals(EmployeeType.FullTime); // System.ArgumentException: 值不应等于FullTime。 (参数 'employeeType')
dateTime.Throw().IfDefault(); // System.ArgumentException: 值不应为默认值。 (参数 'dateTime') dateTime.Throw().IfNotDefault(); // System.ArgumentException: 值应为默认值。 (参数 'dateTime') number.Throw().IfEquals(5); // System.ArgumentException: 值不应等于5。 (参数 'number') number.Throw().IfNotEquals(3); // System.ArgumentException: 值应等于3。 (参数 'number')
uri.Throw().IfHttps(); // System.ArgumentException: Uri方案不应该是https。(参数'uri') uri.Throw().IfNotHttps(); // System.ArgumentException: Uri方案应该是https。(参数'uri') uri.Throw().IfHttp(); // System.ArgumentException: Uri方案不应该是http。(参数'uri') uri.Throw().IfNotHttp(); // System.ArgumentException: Uri方案应该是http。(参数'uri') uri.Throw().IfScheme(Uri.UriSchemeHttp); // System.ArgumentException: Uri方案不应该是http。(参数'uri') uri.Throw().IfSchemeNot(Uri.UriSchemeFtp); // System.ArgumentException: Uri方案应该是ftp。(参数'uri') uri.Throw().IfPort(800); // System.ArgumentException: Uri端口不应该是80。(参数'uri') uri.Throw().IfPortNot(8080); // System.ArgumentException: Uri端口应该是8080。(参数'uri') uri.Throw().IfAbsolute(); // System.ArgumentException: Uri应该是相对的。(参数'uri') uri.Throw().IfRelative(); // System.ArgumentException: Uri应该是绝对的。(参数'uri') uri.Throw().IfNotAbsolute(); // System.ArgumentException: Uri应该是绝对的。(参数'uri') uri.Throw().IfNotRelative(); // System.ArgumentException: Uri应该是相对的。(参数'uri') uri.Throw().IfHost("www.google.com"); // System.ArgumentException: Uri主机不应该是www.google.com。(参数'uri') uri.Throw().IfHostNot("www.google.com"); // System.ArgumentException: Uri主机应该是www.google.com。(参数'uri')
int、double、decimal、long、float、short、DateTime、DateOnly、TimeOnly等)number.Throw().IfPositive(); // System.ArgumentOutOfRangeException: 值不应该大于0。(参数'number')\n 实际值为5。 number.Throw().IfNegative(); // System.ArgumentOutOfRangeException: 值不应该小于0。(参数'number')\n 实际值为-5。 number.Throw().IfLessThan(10); // System.ArgumentOutOfRangeException: 值不应该小于10。(参数'number')\n 实际值为5。 number.Throw().IfGreaterThan(3); // System.ArgumentOutOfRangeException: 值不应该大于3。(参数'number')\n 实际值为5。 number.Throw().IfGreaterThanOrEqualTo(5); // System.ArgumentOutOfRangeException: 值不应该大于或等于5。(参数'number')\n 实际值为6。 number.Throw().IfLessThanOrEqualTo(5); // System.ArgumentOutOfRangeException: 值不应该小于或等于5。(参数'number')\n 实际值为4。 number.Throw().IfPositiveOrZero(); // System.ArgumentOutOfRangeException: 值不应该大于或等于0。(参数'number')\n 实际值为4。 number.Throw().IfNegativeOrZero(); // System.ArgumentOutOfRangeException: 值不应该小于或等于0。(参数'number')\n 实际值为-1。 number.Throw().IfOutOfRange(0, 5); // System.ArgumentOutOfRangeException: 值应该在0和5之间。(参数'number')\n 实际值为-5。 number.Throw().IfInRange(0, 5); // System.ArgumentOutOfRangeException: 值不应该在0和5之间。(参数'number')\n 实际值为4。
myObject.Throw().IfType<string>(); // System.ArgumentException: 参数不应该是'String'类型。(参数'myObject')。 myObject.Throw().IfNotType<string>(); // System.ArgumentException: 参数应该是'String'类型。(参数'myObject')。
person.Throw().IfTrue(p => p.IsFunny); // System.ArgumentException: 值不应满足条件(条件:'person => person.IsFunny')。(参数'person') person.Throw().IfFalse(p => p.IsFunny); // System.ArgumentException: 值应满足条件(条件:'person => person.IsFunny')。(参数'person') // 我们可以将异常抛出逻辑内联到方法调用中。 Person person = GetPerson().Throw().IfTrue(person => person.Age < 18); // System.ArgumentException: 值不应满足条件(条件:'person => person.Age < 18')。(参数'GetPerson()')
person.Throw().IfEmpty(p => p.Name); // System.ArgumentException: 字符串不应为空。(参数'person: p => p.Name') person.Throw().IfWhiteSpace(p => p.Name); // System.ArgumentException: 字符串不应仅包含空白字符。(参数'person: p => p.Name') person.Throw().IfNullOrWhiteSpace(p => p.Name); // System.ArgumentException: 字符串不应为null或仅包含空白字符。(参数'person: p => p.Name') person.Throw().IfNullOrEmpty(p => p.Name); // System.ArgumentException: 字符串不应为null或空。(参数'person: p => p.Name') person.Throw().IfLengthEquals(p => p.Name, 7); // System.ArgumentException: 字符串长度不应等于7。(参数'person: p => p.Name') person.Throw().IfLengthNotEquals(p => p.Name, 10); // System.ArgumentException: 字符串长度应等于10。(参数'person: p => p.Name') person.Throw().IfShorterThan(p => p.Name, 10); // System.ArgumentException: 字符串不应短于10个字符。(参数'person: p => p.Name') person.Throw().IfLongerThan(p => p.Name, 3); // System.ArgumentException: 字符串不应长于3个字符。(参数'person: p => p.Name') person.Throw().IfEquals(p => p.Name, "Amichai"); // System.ArgumentException: 字符串不应等于'Amichai'(比较类型:'Ordinal')。(参数'person: p => p.Name') person.Throw().IfEquals(p => p.Name, "Amichai", StringComparison.InvariantCulture); // System.ArgumentException: 字符串不应等于'Amichai'(比较类型:'InvariantCulture')。(参数'person: p => p.Name') person.Throw().IfEqualsIgnoreCase(p => p.Name, "AMICHAI"); // System.ArgumentException: 字符串不应等于'AMICHAI'(比较类型:'OrdinalIgnoreCase')。(参数'person: p => p.Name') person.Throw().IfNotEquals(p => p.Name, "Dan"); // System.ArgumentException: 字符串应等于'Dan'(比较类型:'Ordinal')。(参数'person: p => p.Name') person.Throw().IfNotEquals(p => p.Name, "Dan", StringComparison.InvariantCultureIgnoreCase); // System.ArgumentException: 字符串应等于'Dan'(比较类型:'InvariantCultureIgnoreCase')。(参数'person: p => p.Name') person.Throw().IfNotEqualsIgnoreCase(p => p.Name, "Dan"); // System.ArgumentException: 字符串应等于'Dan'(比较类型:'OrdinalIgnoreCase')。(参数'person: p => p.Name') person.Throw().IfContains(p => p.Name, "substring"); // System.ArgumentException: 字符串不应包含'substring'(比较类型:'Ordinal')。(参数'person: p => p.Name') person.Throw().IfContains(p => p.Name, "substring", ComparisonType.InvariantCulture); // System.ArgumentException: 字符串应包含'substring'(比较类型:'InvariantCulture')。(参数'person: p => p.Name') person.Throw().IfNotContains(p => p.Name, "substring"); // System.ArgumentException: 字符串应包含'substring'(比较类型:'Ordinal')。(参数'person: p => p.Name') person.Throw().IfNotContains(p => p.Name, "substring", ComparisonType.InvariantCultureIgnoreCase); // System.ArgumentException: 字符串应包含'substring'(比较类型:'InvariantCultureIgnoreCase')。(参数'person: p => p.Name') person.Throw().IfStartsWith(p => p.Name, "Jer"); // System.ArgumentException: 字符串不应以'Jer'开头(比较类型:'Ordinal')。(参数'person: p => p.Name') person.Throw().IfStartsWith(p => p.Name, "JER", StringComparison.OrdinalIgnoreCase); // System.ArgumentException: 字符串不应以'JER'开头(比较类型:'OrdinalIgnoreCase')。(参数'person: p => p.Name') person.Throw().IfNotStartsWith(p => p.Name, "dan"); // System.ArgumentException: 字符串应以'dan'开头(比较类型:'Ordinal')。(参数'person: p => p.Name') person.Throw().IfNotStartsWith(p => p.Name, "dan", StringComparison.InvariantCultureIgnoreCase); // System.ArgumentException: 字符串应以'dan'开头(比较类型:'InvariantCultureIgnoreCase')。(参数'person: p => p.Name') person.Throw().IfEndsWith(p => p.Name, "emy"); // System.ArgumentException: 字符串不应以'emy'结尾(比较类型:'Ordinal')。(参数'person: p => p.Name') person.Throw().IfEndsWith(p => p.Name, "EMY", StringComparison.OrdinalIgnoreCase); // System.ArgumentException: 字符串不应以'EMY'结尾(比较类型:'OrdinalIgnoreCase')。(参数'person: p => p.Name') person.Throw().IfNotEndsWith(p => p.Name, "dan"); // System.ArgumentException: 字符串应以'dan'结尾(比较类型:'Ordinal')。(参数'person: p => p.Name') person.Throw().IfNotEndsWith(p => p.Name, "dan", StringComparison.OrdinalIgnoreCase); // System.ArgumentException: 字符串应以'dan'结尾(比较类型:'OrdinalIgnoreCase')。(参数'person: p => p.Name') person.Throw().IfMatches(p => p.Name, "J.*y"); // System.ArgumentException: 字符串不应匹配正则表达式模式'J.*y'(参数'person: p => p.Name') person.Throw().IfMatches(p => p.Name, "[a-z]{0,10}", RegexOptions.IgnoreCase); // System.ArgumentException: 字符串不应匹配正则表达式模式'[a-z]{0,10}'(参数'person: p => p.Name') person.Throw().IfNotMatches(p => p.Name, "^[0-9]+$"); // System.ArgumentException: 字符串应匹配正则表达式模式'^[0-9]+$'(参数'person: p => p.Name') person.Throw().IfNotMatches(p => p.Name, "abc ", RegexOptions.IgnorePatternWhitespace); // System.ArgumentException: 字符串应匹配正则表达式模式'^[0-9]+$'(参数'person: p => p.Name')
person.Throw().IfHasNullElements(p => p.Friends); // System.ArgumentException: 集合不应包含null元素。(参数'person: p => p.Friends') person.Throw().IfEmpty(p => p.Friends); // System.ArgumentException: 集合不应为空。(参数'person: p => p.Friends') person.Throw().IfNotEmpty(p => p.Friends); // System.ArgumentException: 集合应为空。(参数'person: p => p.Friends') person.Throw().IfCountLessThan(p => p.Friends, 5); // System.ArgumentException: 集合数量不应少于5。(参数'person: p => p.Friends') person.Throw().IfCountGreaterThan(p => p.Friends, 1); // System.ArgumentException: 集合数量不应大于1。(参数'person: p => p.Friends') person.Throw().IfCountEquals(p => p.Friends, 0); // System.ArgumentException: 集合数量不应等于0。(参数'person: p => p.Friends') person.Throw().IfCountNotEquals(p => p.Friends, 0); // System.ArgumentException: 集合数量应等于0。(参数'person: p => p.Friends') person.Throw().IfContains(p => p.Friends, "Amichai"); // System.ArgumentException: 集合不应包含元素。(参数'person: p => p.Friends') person.Throw().IfNotContains(p => p.Friends, "Amichai"); // System.ArgumentException: 集合应包含元素。(参数'person: p => p.Friends')
person.Throw().IfUtc(p => p.DateOfBirth); // System.ArgumentException: 值不应为Utc。 (参数 'person: p => p.DateOfBirth') person.Throw().IfNotUtc(p => p.DateOfBirth); // System.ArgumentException: 值应为Utc。 (参数 'person: p => p.DateOfBirth') person.Throw().IfDateTimeKind(p => p.DateOfBirth, DateTimeKind.Unspecified); // System.ArgumentException: 值不应为Unspecified。 (参数 'person: p => p.DateOfBirth') person.Throw().IfDateTimeKindNot(p => p.DateOfBirth, DateTimeKind.Local); // System.ArgumentException: 值应为Local。 (参数 'person: p => p.DateOfBirth') person.Throw().IfGreaterThan(p => p.DateOfBirth, DateTime.Now.AddYears(-20)); // System.ArgumentOutOfRangeException: 值不应大于 2/28/2002 4:41:19 PM。 (参数 'person: p => p.DateOfBirth') person.Throw().IfLessThan(p => p.DateOfBirth, DateTime.Now.AddYears(20)); // System.ArgumentOutOfRangeException: 值不应小于 2/28/2042 4:41:46 PM。 (参数 'person: p => p.DateOfBirth') person.Throw().IfEquals(p => p.DateOfBirth, other); // System.ArgumentException: 值不应等于 2/28/2022 4:45:12 PM。 (参数 'person: p => p.DateOfBirth')
person.Throw().IfOutOfRange(p => p.EmployeeType); // System.ArgumentOutOfRangeException: 值应在枚举中定义。 (参数 'person: p => p.EmployeeType') person.Throw().IfEquals(p => p.EmployeeType, EmployeeType.FullTime); // System.ArgumentException: 值不应等于FullTime。 (参数 'person: p => p.EmployeeType')
person.Throw().IfDefault(p => p.DateOfBirth); // System.ArgumentException: 值不应为默认值。 (参数 'person: p => p.DateOfBirth') person.Throw().IfNotDefault(p => p.DateOfBirth); // System.ArgumentException: 值应为默认值。 (参数 'person: p => p.DateOfBirth') person.Throw().IfNull(p => p.MiddleName); // System.ArgumentNullException: 值不能为null。 (参数 'person: p => p.MiddleName') person.Throw().IfNotNull(p => p.MiddleName); // System.ArgumentException: 值应为null。 (参数 'person: p => p.MiddleName') person.Throw().IfEquals(p => p.Age, 5); // System.ArgumentException: 值不应等于5。 (参数 'person: p => p.Age') person.Throw().IfNotEquals(p => p.Age, 3); // System.ArgumentException: 值应等于3。 (参数 'person: p => p.Age')
person.Throw().IfHttps(p => p.Website); // System.ArgumentException: Uri协议不应为https。 (参数 'person: p => p.Website') person.Throw().IfNotHttps(p => p.Website); // System.ArgumentException: Uri协议应为https。 (参数 'person: p => p.Website') person.Throw().IfHttp(p => p.Website); // System.ArgumentException: Uri协议不应为http。 (参数 'person: p => p.Website') person.Throw().IfNotHttp(p => p.Website); // System.ArgumentException: Uri协议应为http。 (参数 'person: p => p.Website') person.Throw().IfScheme(p => p.Website, Uri.UriSchemeHttp); // System.ArgumentException: Uri协议不应为http。 (参数 'person: p => p.Website') person.Throw().IfSchemeNot(p => p.Website, Uri.UriSchemeFtp); // System.ArgumentException: Uri协议应为ftp。 (参数 'person: p => p.Website') person.Throw().IfPort(p => p.Website, 800); // System.ArgumentException: Uri端口不应为80。 (参数 'person: p => p.Website') person.Throw().IfPortNot(p => p.Website, 8080); // System.ArgumentException: Uri端口应为8080。 (参数 'person: p => p.Website') person.Throw().IfAbsolute(p => p.Website); // System.ArgumentException: Uri应为相对路径。 (参数 'person: p => p.Website') person.Throw().IfRelative(p => p.Website); // System.ArgumentException: Uri应为绝对路径。 (参数 'person: p => p.Website') person.Throw().IfNotAbsolute(p => p.Website); // System.ArgumentException: Uri应为绝对路径。 (参数 'person: p => p.Website') person.Throw().IfNotRelative(p => p.Website); // System.ArgumentException: Uri应为相对路径。 (参数 'person: p => p.Website') person.Throw().IfHost(p => p.Website, "www.google.com"); // System.ArgumentException: Uri主机不应为www.google.com。 (参数 'person: p => p.Website') person.Throw().IfHostNot(p => p.Website, "www.google.com"); // System.ArgumentException: Uri主机应为www.google.com。 (参数 'person: p => p.Website')
person.Throw().IfPositive(p => p.Age); // System.ArgumentOutOfRangeException: 值不应大于0。 (参数 'person: p => p.Age')\n 实际值为5。 person.Throw().IfNegative(p => p.Age); // System.ArgumentOutOfRangeException: 值不应小于0。 (参数 'person: p => p.Age')\n 实际值为-5。 person.Throw().IfLessThan(p => p.Age, 10); // System.ArgumentOutOfRangeException: 值不应小于10。 (参数 'person: p => p.Age')\n 实际值为5。 person.Throw().IfGreaterThan(p => p.Age, 3); // System.ArgumentOutOfRangeException: 值不应大于3。 (参数 'person: p => p.Age')\n 实际值为5。 person.Throw().IfGreaterThanOrEqualTo(p => p.Age, 5); // System.ArgumentOutOfRangeException: 值不应大于或等于5。 (参数 'person: p => p.Age')\n 实际值为6。 person.Throw().IfLessThanOrEqualTo(p => p.Age, 5); // System.ArgumentOutOfRangeException: 值不应小于或等于5。 (参数 'person: p => p.Age')\n 实际值为4。 person.Throw().IfPositiveOrZero(p => p.Age); // System.ArgumentOutOfRangeException: 值不应大于或等于0。 (参数 'person: p => p.Age')\n 实际值为4。 person.Throw().IfNegativeOrZero(p => p.Age); // System.ArgumentOutOfRangeException: 值不应小于或等于0。 (参数 'person: p => p.Age')\n 实际值为-1。 person.Throw().IfOutOfRange(p => p.Age, 0, 5); // System.ArgumentOutOfRangeException: 值应在0和5之间。 (参数 'person: p => p.Age')\n 实际值为-5。 person.Throw().IfInRange(p => p.Age, 0, 5); // System.ArgumentOutOfRangeException: 值不应在0和5之间。 (参数 'person: p => p.Age')\n 实际值为4。
你可以通过添加自己的规则轻松扩展该库。
这里有一个简单的例子:
"foo".Throw().IfFoo(); // System.ArgumentException: 字符串不应等于'foo' (参数 '"foo"')
namespace Throw { public static class ValidatableExtensions { public static ref readonly Validatable<string> IfFoo(this in Validatable<string> validatable) { if (string.Equals(validatable.Value, "foo", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("字符串不应等于'foo'", validatable.ParamName); } return ref validatable; } } }
另一个例子:
user.Throw().IfUsesFacebookOnChrome();
namespace Throw { public static class ValidatableExtensions { public static ref readonly Validatable<User> IfUsesFacebookOnChrome(this in Validatable<User> validatable) { if (validatable.Value.FavoriteBrowser == Browser.Chrome && validatable.Value.FavoriteWebsite == new Uri("https://facebook.com")) { throw new UserException("用户不应在Chrome上使用Facebook!"); } return ref validatable; } } }
如果你想在扩展中使用异常自定义,你可以使用ExceptionThrower类,它知道如何根据自定义创建适当的异常。例如:
namespace Throw { public static class ValidatableExtensions { public static ref readonly Validatable<User> IfUsesFacebookOnChrome(this in Validatable<User> validatable) { if (validatable.Value.FavoriteBrowser == Browser.Chrome && validatable.Value.FavoriteWebsite == new Uri("https://facebook.com")) { ExceptionThrower.Throw(validatable.ParamName, validatable.ExceptionCustomizations, "用户不应在Chrome上使用Facebook。"); } return ref validatable; } } }
这将表现如下:
user.Throw() .IfUsesFacebookOnChrome(); // System.ArgumentException: 用户不应在Chrome上使用Facebook。 (参数 'user')
user.Throw("一条不同的消息。") .IfUsesFacebookOnChrome(); // System.ArgumentException: 一条不同的消息。 (参数 'user')
user.Throw(() => new Exception("一个不同的异常。")) .IfUsesFacebookOnChrome(); // System.Exception: 一个不同的异常。
user.Throw(paramName => new Exception($"一个不同的异常 。参数名: '{paramName}'")) .IfUsesFacebookOnChrome(); // System.Exception: 一个不同的异常。参数名: 'user'
有一个你想从发布版本中排除的Throw()规则吗?
只需在规则中添加OnlyInDebug(),它就会从非调试版本中排除。
"foo".Throw().IfEquals("foo").OnlyInDebug();
dotnet run -c Debug # 将抛出异常
dotnet run -c Release # 不会抛出异常
欢迎提出任何想法、错误或功能请求的问题。
我们正在努力成为最快的验证库,所以如果你有改进运行时速度的建议,请与我们分享。
本项目根据MIT许可证条款授权。


职场AI,就用扣子
AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!


多风格AI绘画神器
堆友平台由阿里巴巴设计团队创建,作为一款AI驱动的设计工具,专为设计师提供一站式增长服务。功能覆盖海量3D素材、AI绘画、实时渲染以及专业抠图,显著提升设计品质和效率。平台不仅提供工具,还是一个促进创意交流和个人发展的空间,界面友好,适合所有级别的设计师和创意工作者。


零代码AI应用开发平台
零代码AI应用开发平台,用户只需一句话简单描述需求,AI能自动生成小程序、APP或H5网页应用,无需编写代码。


免费创建高清无水印Sora视频
Vora是一个免费创建高清无水印Sora视频的AI工具


最适合小白的AI自动化工作流平台
无需编码,轻松生成可复用、可变现的AI自动化工作流

大模型驱动的Excel数据处理工具
基于大模型交互的表格处理系统,允许用户通过对话方式完成数据整理和可视化分析。系统采用机器学习算法解析用户指令,自动执行排序、公式计算和数据透视等操作,支持多种文件格式导入导出。数据处理响应速度保持在0.8秒以内,支持超过100万行数据的即时分析。


AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。