人们在管理班级guard clause爆炸时采取了哪些方法(如果有的话)?例如:
public void SomeMethod<T>(string var1, IEnumerable<T> items, int count)
{
if (string.IsNullOrEmpty(var1))
{
throw new ArgumentNullException("var1");
}
if (items == null)
{
throw new ArgumentNullException("items");
}
if (count < 1)
{
throw new ArgumentOutOfRangeException("count");
}
... etc ....
}
在我目前正在进行的项目中,有许多类在公共方法上具有类似的一组保护条款。
我知道.NET 4.0代码合约,但目前这不是我们团队的选择。
答案 0 :(得分:46)
我见过很多项目都使用静态Guard
类。
public static class Guard {
public static void ArgumentIsNotNull(object value, string argument) {
if (value == null)
throw new ArgumentNullException(argument);
}
}
在我看来,它使代码更清晰。
Guard.ArgumentIsNotNull(arg1, "arg1");
答案 1 :(得分:4)
如果您不想遵守Code Contracts路线,简化它的一种方法是删除大括号:
public void SomeMethod<T>(string var1, IEnumerable<T> items, int count)
{
if (string.IsNullOrEmpty(var1))
throw new ArgumentNullException("var1");
if (items == null)
throw new ArgumentNullException("items");
if (count < 1)
throw new ArgumentOutOfRangeException("count");
... etc ....
}
除此之外,如果你的异议是.Net 4.0还不是黄金时段,你可以通过一些方法来模拟代码合同:
http://geekswithblogs.net/Podwysocki/archive/2008/01/22/118770.aspx
答案 2 :(得分:4)
您可以考虑重构为Introduce a Null Object。
答案 3 :(得分:3)
与此同时,这里有一篇很好的文章:http://haacked.com/archive/2013/01/05/mitigate-the-billion-dollar-mistake-with-aspects.aspx/
我会考虑使用NullGuard.Fody因为我对Fodys减少样板代码的能力感到兴奋
答案 4 :(得分:3)
减少(不完全删除)保护条款数量的一种方法是了解它们存在的原因。通常情况下,我们会防止对参数类型有效的值,但对接受它们的方法无效。换句话说,方法是在由参数类型定义的域的子集上定义的。
此类案例的解决方案是尝试定义子类型(例如限制性更强的接口)并接受该类型作为参数。您可以在本文中找到一个说明性示例:Why do We Need Guard Clauses?
当然,这种技术并不适用于所有情况。所有引用类型至少允许空引用。因此,我们的大多数方法都将在域的一部分上定义,而这又需要一个针对null的保护子句。
但从积极的方面来看,这种技术有助于提高对接收比预期更普遍的参数的方法的认识。管道那个孔有助于改善设计。