【发布时间】:2016-01-15 12:53:26
【问题描述】:
我正在构建一个简单的 Guard API 以防止将非法参数传递给函数等。
我有以下代码:
public static class Guard
{
public static GuardArgument<T> Ensure<T>(T value, string argumentName)
{
return new GuardArgument<T>(value, argumentName);
}
}
public class GuardArgument<T>
{
public GuardArgument(T value, string argumentName)
{
Value = value;
Name = Name;
}
public T Value { get; private set; }
public string Name { get; private set; }
}
// Example extension for validity checks
public static GuardArgument<T> IsNotNull<T>(this GuardArgument<T> guardArgument, string errorMessage)
{
if (guardArgument.Value == null)
{
throw new ArgumentNullException(guardArgument.Name, errorMessage);
}
return guardArgument;
}
目前,代码可以以类似的方式使用(注意这只是一个愚蠢的例子):
void DummyMethod(int? someObject) {
Guard.Ensure(someObject, "someObject")
.IsNotNull()
.IsGreaterThan(0)
.IsLessThan(10);
}
这一切都很好。我现在想要做的是扩展 API 以通过以下方式在检查中包含子属性:
Guard.Ensure(someObject, "someObject")
.IsNotNull()
.Property(
(x => x.ChildProp1, "childProp1")
.IsNotNull()
.IsGreaterThan(10)
)
.Property(
(x => x.ChildProp2, "childProp2")
.IsNotNull()
.IsLessThan(10)
);
显然,新的.Property 方法需要返回父GuardArgument 才能链接。此外,子属性需要能够使用现有的检查方法(IsNotNull() 等)以避免代码重复。
我不知道如何构造 lambda/Property 函数参数或 .Property 方法的位置 - 即它应该是 GuardArgument 或其他地方的属性,或者即使有更好的结构到 API。
【问题讨论】:
-
可能是错字,但 GuardArgument 构造函数设置了
Name = Name -
您说,“显然新的
.Property方法需要返回父GuardArgument才能链接。” - 不,这是不正确的。如果您正在尝试制作流畅的 API,那么您不应该传递父级 - 您应该构造一个新的GuardArgument嵌套父级,否则您可以通过保留链上的引用然后尝试构建新链来创建可怕的错误来自他们。