質問は少し前に回答されましたが、最近同じ問題について考えています。形式化されたコード コントラクト (自動検証またはチェックを使用) は良い考えのようですが、一般的に、それらの検証機能はかなり制限されており、null または空の文字列のチェックなどの単純なチェックには、同じくらい多くのコード (またはそれ以上) が必要です。 )昔ながらのチェックよりも。
皮肉なことに、文字列の場合の私の意見では、null、空、または空白ではないことがチェックされた文字列をラップし、このインスタンスを渡す 1 つまたは 2 つのクラスが実際に最良の答えです。
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 かどうかをチェックする必要がなくなるわけではありませんが、いくつかの大きな利点があります。
- 空または空白の文字列を何度もチェックする必要はありません。これは、文字列が頻繁に渡される状況でエラーが発生しやすくなる可能性があります。
- 実装で行ったように、null のチェックは、空の値 (または空白値) のチェックとは異なります。前者の場合は特定の ArgumentNullException をスローし、2 番目の場合は ArgumentException をスローする必要があるためです。
- これは、文字列の値に対する制約を明確に示しています。これは、ラッピング クラスが行うべきことと同じです。実際、何らかの制約があり、頻繁に渡される文字列がある場合は、チェックをカプセル化し、残りのコードが問題にならないようにするクラスでラップすることを常にお勧めします。この良い例は、特定の正規表現を満たす必要がある文字列です。しかし、私はここで質問から逸れています...