重构保护子句

发布于 2024-08-09 05:21:18 字数 609 浏览 5 评论 0原文

人们采取什么方法(如果有的话)来管理类中的保护条款爆炸?例如:

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 代码合同,但是目前我们团队还没有选择。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

丑疤怪 2024-08-16 05:21:18

我见过的很多项目都使用静态 Guard 类。

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

在我看来,它使代码更加简洁。

Guard.ArgumentIsNotNull(arg1, "arg1");

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");
兔姬 2024-08-16 05:21:18

您可以考虑重构为引入空对象

You might consider refactoring to Introduce a Null Object.

暖心男生 2024-08-16 05:21:18

同时,这里有一篇关于此的优秀文章: http://haacked.com/archive/2013/01/05/mitigate-the-billion-dollar-mistake-with-aspects.aspx/

我会考虑使用 NullGuard.Fody 因为我对 Fody 减少样板代码的能力感到兴奋

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

黄昏下泛黄的笔记 2024-08-16 05:21:18

减少(而不是完全消除)保护子句数量的一种方法是了解它们存在的原因。很多时候,我们会防范对参数类型有效但对接受它们的方法无效的值。换句话说,方法是在参数类型定义的域的子集上定义的。

此类情况的解决方案是尝试定义一个子类型(例如,更具限制性的接口)并接受该类型作为参数。您可以在本文中找到一个说明性示例:为什么这样做我们需要保护子句吗?

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

但从积极的一面来看,这种技术有助于提高人们对接收比预期更笼统的参数的方法的认识。对该孔进行管道连接有助于改善总体设计。

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.

紫轩蝶泪 2024-08-16 05:21:18

如果您不想走代码契约路线,简化它的一种方法是删除大括号:

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文