Refactoring Guard Clauses

别来无恙 提交于 2019-11-29 22:18:19
David Brown

A lot of projects that I've seen use a static Guard class.

public static class Guard {
    public static void ArgumentIsNotNull(object value, string argument) {
        if (value == null)
            throw new ArgumentNullException(argument);
    }
}

It makes the code a lot cleaner, in my opinion.

Guard.ArgumentIsNotNull(arg1, "arg1");

If you don't want to go down the Code Contracts route, one way to simplify it is to remove the braces:

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 ....
}

Other than that, there are some ways that you can simulate Code Contracts, if your objection is that .Net 4.0 is not prime time yet:

http://geekswithblogs.net/Podwysocki/archive/2008/01/22/118770.aspx

You might consider refactoring to Introduce a Null Object.

Meanwhile there's an excellent article about this here: http://haacked.com/archive/2013/01/05/mitigate-the-billion-dollar-mistake-with-aspects.aspx/

I would consider to use NullGuard.Fody as I'm excited about Fodys abilities to reduce boilerplate code

One approach to reducing (not completely removing) number of guard clauses is to understand the cause of their existence. Quite often, it turns that we guard against values that are valid for the type of the argument, but not valid for the method that accepts them. In other words, method is defined on a subset of the domain defined by the argument type.

Solution to this category of cases is to try to define a subtype (e.g. a more restrictive interface) and to accept that type as the argument. You can find an illustrative example in this article: Why do We Need Guard Clauses?

Of course, this technique does not apply to all cases. All reference types at least allow null references. Consequently, most of our methods will be defined on part of the domain, which in turn requires a guard clause against null.

But on the positive side, this technique helps grow awareness of methods that receive arguments that are more general than desired. Plumbing that hole helps improve design in general.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!