2009-10-20 43 views
20

在您的班级中管理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 .... 
} 

在我目前正在研究的项目中,有许多类在公共方法上有一组类似的guard子句。

我知道的.NET 4.0代码契约的但是这不是我们球队目前的一个选项。

回答

39

很多项目,我已经看到了使用静态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

我只是发布相同的东西。唯一的问题是它把这个方法放在堆栈跟踪的顶端,而不是顶端的方法,而不是它那么大。这种模式显然可以用于不同的类型来检查一系列的值,等等...... – 2009-10-20 23:42:59

+0

是的,这是我曾经遇到过的唯一问题。虽然很容易找到原始的调用方法。 – 2009-10-20 23:46:19

+1

这与模拟代码合同的类基本相同。 – 2009-10-21 03:25:38

5

如果你不想下去代码契约路线,简化它的一种方式是去除括号:

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

+0

看在上帝的份上,不要这样做!如果没有大括号的陈述是一个很好的方式来解决问题。 – EricRRichards 2018-02-27 15:04:06

+1

@EricRRichards:* [耸耸肩] *坦率地说,如果程序员不能在没有大括号的情况下保持代码不变(特别是像这样的不起眼的代码),他们可能应该回到学校。 – 2018-02-27 15:47:35

3

一种方法减少样板代码减少(不完全去除)号守卫条款的目的是了解他们存在的原因。通常情况下,我们会防范对参数类型有效的值,但对接受它们的方法无效。换句话说,方法是在由参数类型定义的域的子集上定义的。

解决这一类箱子是尝试定义一个子类型(例如,更具限制性的接口),并接受该类型作为参数。您可以在这篇文章中找到一个说明性的例子:Why do We Need Guard Clauses?

当然,这种技术并不适用于所有情况。所有引用类型至少允许空引用。因此,我们的大部分方法都将在域的一部分上定义,而这又需要一个针对null的guard子句。

但积极的一面,这种技术有助于成长的接收是更普遍比所需的参数方法意识。一般来说,通过管道来帮助改善设计。