Refactoring Guard Clauses

感情迁移 提交于 2019-12-18 10:33:07

问题


What approaches do people take (if any) in managing guard clause explosion in your classes? For example:

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

In the project that I am currently working on there are many classes that have a similar set of guard clauses on the public methods.

I am aware of the .NET 4.0 Code Contracts however this is not an option for our team at the moment.


回答1:


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");



回答2:


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




回答3:


You might consider refactoring to Introduce a Null Object.




回答4:


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




回答5:


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.



来源:https://stackoverflow.com/questions/1597884/refactoring-guard-clauses

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