18

我不知道有多少次我不得不编写代码来验证字符串参数:

public RoomName(string name)
{
    if (string.IsNullOrEmpty(name))
    {
        throw new ArgumentException("Cannot be empty", "name");
    }
}

有没有办法避免这种情况?是否有一些属性或按合同设计的机制来避免这种情况?有没有办法说:

public RoomName(NotNullOrEmptyString name)
{

无需实际创建该类型?

4

3 回答 3

7

您可以通过带有属性的代码注入来做到这一点。

节省一些编码时间但仍然给你很多控制权的另一个选择是使用像CuttingEdge.Conditions这样的东西。这为参数检查提供了一个流畅的接口,因此您可以编写:

name.Requires().IsNotNull();
于 2009-07-10T00:56:42.550 回答
1

虽然这个问题已经回答了一段时间,但我最近一直在思考同样的问题。形式化的代码合约(带有自动验证或检查)似乎是一个好主意,但一般来说,它们的验证能力非常有限,对于像空字符串或空字符串检查这样的简单检查,它们需要同样多的代码(或更多) 比老式支票。

具有讽刺意味的是,我认为字符串案例的最佳答案确实是一两个类,它们包装一个已检查为不为空、空或空白的字符串,并传递此实例:

public class NonEmptyString : IComparable<NonEmptyString>, ...
{
    private readonly string _value;

    public NonEmptyString(string value)
    {
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }
        if (value.Length == 0)
        {                
            throw NewStringIsEmptyException("value");
        }
        _value = value;
    }

    public string Value
    {
        get { return _value; }
    }

    ...
}

public class NonWhiteSpaceString : NonEmptyString
{
    ....
}

当然,传递这些实例并不会阻止您检查它们本身是否为空,但它有一些很大的优势:

  • 您不必一遍又一遍地检查空字符串或空白字符串,这在字符串被大量传递的情况下很容易出错。
  • 正如我在实现中所做的那样,检查 null 与检查空值(或空白值)不同,因为您想在前一种情况下抛出特定的 ArgumentNullException,在第二种情况下抛出一些 ArgumentException。
  • 它清楚地表明了对字符串值的约束,就像任何包装类应该做的那样。事实上,如果你有一个有任何约束的字符串,并且它被大量传递,我总是建议将它包装在一个封装检查的类中,并使其余代码免受麻烦。一个很好的例子是必须满足某个正则表达式的字符串。但是,我在这里转移了这个问题......
于 2011-11-08T08:01:37.187 回答
0

另请参阅C#:如何实现和使用 NotNull 和 CanBeNull 属性以获取有关代码协定的更多信息,它们现在如何在 VS2008 中实现,以及它们将如何集成到 VS2010 中。

于 2009-07-10T00:54:21.693 回答