C# 8 使用实用方法验证参数
C# 8 validate arguments with utility method
假设我有一个接受 nullable reference type 的方法,例如:
int Func(string? param)
{
return param.Length;
}
编译器正确地警告说 param
应该检查 null
。
在 C# 8 之前,我习惯于使用这样的外部实用函数来验证参数:
public static class Validate
{
public static void NotNull(object? value, string parameterName, string? field = null)
{
if (value == null) throw new ArgumentNullException(parameterName + (field == null ? string.Empty : "." + field));
}
}
…
int Func(string? param)
{
Validate.NotNull(param, nameof(param));
return param.Length;
}
在这种情况下,编译器似乎无法检测到参数 param
实际上在 Validate
方法内部检查了 null
,因此仍然会报错。
没有其他方法可以直接测试方法内部的 null
值吗?
int Func(string? param)
{
if (value == null) throw new ArgumentNullException(nameof(param));
return param.Length;
}
我经常使用的一种方法听起来像你正在寻找的是这样的:
public static T MaybeThrow<T>(
this T? pObject,
string? pMaybeErrorMessage = null
) where T : class {
if (pObject == null)
throw new ShouldNotBeNullException(pMaybeErrorMessage);
return pObject;
}
使用了这样的东西:
int Func(string? param) =>
param
.MaybeThrow(nameof(param) + " was null")
.Length;
您可以为此使用 [NotNull]
,因此编译器了解到在调用 Validate.NotNull
之后,该值永远不会是 null
.
using System.Diagnostics.CodeAnalysis;
public static class Validate
{
public static void NotNull([NotNull]object? value, string parameterName, string? field = null)
{
if (value == null) throw new ArgumentNullException(parameterName + (field == null ? string.Empty : "." + field));
}
}
结果:这将不再发出警告:
int Func(string? param)
{
Validate.NotNull(param, nameof(param));
return param.Length;
}
旁注 - Func 方法的签名
当然问题是为什么Func方法没有签名:
int Func(string param) // no null allowed
如果不行,您也可以使用另一个属性 [DisallowNull]
,所以
int Func([DisallowNull] string? param) // gives warning if called with null compile time
旁注 - 更多属性
还有更多超棒的属性
这是我的看法:)
int Func(string? param)
{
return param?.Length ?? throw new ArgumentNullException(nameof(param));
}
假设我有一个接受 nullable reference type 的方法,例如:
int Func(string? param)
{
return param.Length;
}
编译器正确地警告说 param
应该检查 null
。
在 C# 8 之前,我习惯于使用这样的外部实用函数来验证参数:
public static class Validate
{
public static void NotNull(object? value, string parameterName, string? field = null)
{
if (value == null) throw new ArgumentNullException(parameterName + (field == null ? string.Empty : "." + field));
}
}
…
int Func(string? param)
{
Validate.NotNull(param, nameof(param));
return param.Length;
}
在这种情况下,编译器似乎无法检测到参数 param
实际上在 Validate
方法内部检查了 null
,因此仍然会报错。
没有其他方法可以直接测试方法内部的 null
值吗?
int Func(string? param)
{
if (value == null) throw new ArgumentNullException(nameof(param));
return param.Length;
}
我经常使用的一种方法听起来像你正在寻找的是这样的:
public static T MaybeThrow<T>(
this T? pObject,
string? pMaybeErrorMessage = null
) where T : class {
if (pObject == null)
throw new ShouldNotBeNullException(pMaybeErrorMessage);
return pObject;
}
使用了这样的东西:
int Func(string? param) =>
param
.MaybeThrow(nameof(param) + " was null")
.Length;
您可以为此使用 [NotNull]
,因此编译器了解到在调用 Validate.NotNull
之后,该值永远不会是 null
.
using System.Diagnostics.CodeAnalysis;
public static class Validate
{
public static void NotNull([NotNull]object? value, string parameterName, string? field = null)
{
if (value == null) throw new ArgumentNullException(parameterName + (field == null ? string.Empty : "." + field));
}
}
结果:这将不再发出警告:
int Func(string? param)
{
Validate.NotNull(param, nameof(param));
return param.Length;
}
旁注 - Func 方法的签名
当然问题是为什么Func方法没有签名:
int Func(string param) // no null allowed
如果不行,您也可以使用另一个属性 [DisallowNull]
,所以
int Func([DisallowNull] string? param) // gives warning if called with null compile time
旁注 - 更多属性
还有更多超棒的属性
这是我的看法:)
int Func(string? param)
{
return param?.Length ?? throw new ArgumentNullException(nameof(param));
}