web-dev-qa-db-ja.com

プロパティセッターからスローする例外は何ですか?

データがデータベースにリンクされているため、文字列プロパティに最大長の要件があります。呼び出し側がこの長さを超える文字列を設定しようとした場合、どの例外をスローする必要がありますか?

たとえば、次のC#コード:

_public string MyProperty
{
    get
    {
        return _MyBackingField;
    }
    set
    {
        if (value.Length > 100)
            throw new FooException("MyProperty has a maximum length of 100.");

        _MyBackingField = value;
    }
}
_

私はArgumentExceptionを検討しましたが、正しくないようです。 技術的に、それは関数です-MyProperty_set(string value)-ArgumentExceptionのケースは作成できますが、消費者の目からは関数として呼び出されていません-それは代入演算子の右側。

この質問は、プロパティセッターで行われるすべての種類のデータ検証を含めるように拡張することもできますが、上記のケースに特に興味があります。

49
lc.

System.String.StringBuilder.Capacityなどの同様の状況で、リフレクターを使用してmscorlib.dllを確認します。Microsoftは、次のようなArgumentOutOfRangeException()を使用します。

public int PropertyA
{
    get
    {
        return //etc...
    }
    set
    {
        if (condition == true)
        {
            throw new ArgumentOutOfRangeException("value", "/* etc... */");
        }
        // ... etc
    }
}
46
Richard Slater

私にとって、ArgumentException(または子)の方が理にかなっています。これは、指定した引数(値)が無効であり、ArgumentExceptionが作成された理由です。

16
Davide Vosti

例外は一切投げません。むしろ、任意の長さの文字列を許可し、保存する前に呼び出されるクラスに別の「Validate」メソッドを設定します。特にデータバインディングを使用する場合、プロパティセッターから例外をスローすると混乱する可能性のあるシナリオがいくつかあります。

プロパティセッターから例外をスローする際の問題は、プログラマが例外をキャッチするのを忘れていることです。それは、データがどの程度クリーンになると期待できるかに依存します。この場合、長い文字列の長さは例外的ではなく一般的であると予想されるため、例外の使用は「例外を伴うフロー制御」になります。

Microsoftの クラスライブラリ開発の設計ガイドライン から引用するには:

可能であれば、通常の制御フローに例外を使用しないでください。システム障害と潜在的な競合状態を伴う操作を除いて、フレームワーク設計者は、ユーザーが例外をスローしないコードを記述できるようにAPIを設計する必要があります。たとえば、ユーザーが例外をスローしないコードを記述できるように、メンバーを呼び出す前に前提条件を確認する方法を提供できます。

10
Martin Brown

コンピュータサイエンスの問題のうち、間接参照のレベルを1つ追加することで解決される問題をいくつ覚えていますか?

たとえば、FixedLengthStringという新しい型を作成する方法があります。初期化された文字列の長さを検証するthat typeのインスタンスになります-プレーン文字列から型変換を行う変換演算子を使用します。プロパティセッターがそのような型を引数として取る場合、違反は引数/プロパティ例外ではなく、型変換例外になります。

実際には、私はめったにこれをしません。 OO遠すぎると感じますが、場合によっては便利なテクニックになる可能性があるため、ここでは完全性のために言及します。

6
philsquared
public IPAddress Address
{
    get
    {
        return address;
    }
    set
    {
        if(value == null)
        {
            throw new ArgumentNullException("value");
        }
        address = value;
    }
}

[〜#〜] msdn [〜#〜] 経由

5
javros