重构保护条款

时间:2009-10-20 23:27:40

标签: c# validation guard-clause

人们在管理班级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代码合约,但目前这不是我们团队的选择。

5 个答案:

答案 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的保护子句。

但从积极的方面来看,这种技术有助于提高对接收比预期更普遍的参数的方法的认识。管道那个孔有助于改善设计。