虽然这个问题已经回答了一段时间,但我最近一直在思考同样的问题。形式化的代码合约(带有自动验证或检查)似乎是一个好主意,但一般来说,它们的验证能力非常有限,对于像空字符串或空字符串检查这样的简单检查,它们需要同样多的代码(或更多) 比老式支票。
具有讽刺意味的是,我认为字符串案例的最佳答案确实是一两个类,它们包装一个已检查为不为空、空或空白的字符串,并传递此实例:
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。
- 它清楚地表明了对字符串值的约束,就像任何包装类应该做的那样。事实上,如果你有一个有任何约束的字符串,并且它被大量传递,我总是建议将它包装在一个封装检查的类中,并使其余代码免受麻烦。一个很好的例子是必须满足某个正则表达式的字符串。但是,我在这里转移了这个问题......