3

「C#クラス設計ハンドブック」(137ページ)のサンプルクラスは、クラスのみのコンストラクター内から特定のフィールドのクラス検証メソッドを呼び出しません。したがって、基本的にサンプルクラスでは、不良データを含むオブジェクトを作成でき、そのデータに対して検証を行うフィールドのプロパティを呼び出すと、そのデータに対してのみエラーがスローされます。だからあなたは今悪いオブジェクトを持っていて、事後までそれを知りません。

コンストラクターからプロパティを呼び出さない理由がわからないため、初期化中に不正なデータが見つかった場合はすぐにエラーがスローされますか?私はそれらを無駄に電子メールで送信しました...

コンストラクターからプロパティを呼び出すことで次の形式を使用する傾向があります-これは初期化データを検証するための適切な構造ですか?ty

class Foo
{
    private string _emailAddress;

    public Foo(string emailAddress)
    {
        EmailAddress = emailAddress;
    }

    public string EmailAddress
    {
        get { return _emailAddress; }
        set
        {
            if (!ValidEmail(value))
                throw new ArgumentException
                    (string.Format
                    ("Email address {0} is in wrong format", 
                    value));

            _emailAddress = value;
        }
    }


    private static bool ValidEmail(string emailAddress)
    {
        return Regex.IsMatch
            (emailAddress, @"\b[A-Z0-9._%+-]+" +
                           @"@[A-Z0-9.-]+\.[A-Z]{2,4}\b",
                           RegexOptions.IgnoreCase);
    }
}
4

5 に答える 5

2

たとえば、emailAddressがどのレベルでもnullであるかどうかをチェックしていないため、恐ろしいNullReferenceExceptionが発生する可能性があります。その特定のチェックはコンストラクター自体で実行する必要があり、emailAddressがnullの場合は、ArgumentNullExceptionをスローします。残りはサンプルに書かれているので特に問題はありません。ただし、プロパティを仮想化し、このクラスから子を派生させると、いくつかの問題が発生する可能性があります。次に、フィールドの初期化、基本クラスおよび派生クラスのコンストラクターの実行順序が問題になるため、注意が必要です。

于 2009-08-26T23:03:10.607 に答える
2

はい、一般的なアプローチが次の場合:

validオブジェクトのインスタンスのみを取得できることを確認してください

それから私はそれが大好きです。

コンストラクターを使用して、すぐに有効なオブジェクトを作成する必要があります。「コンテナー」だけを作成するのではなく、物を入れるために使用する必要があります。

于 2009-08-26T23:03:31.293 に答える
2

コンストラクターでデータを検証しないことは私には意味がありません。ご指摘のとおり、オブジェクトは無効な状態になる可能性があります。この設計を考えると、ゲッターを呼び出すときにデータが不良であることに気付くことさえありません。

中程度以上の複雑さの場合、私はすぐに例外をスローするのではなく、BrokenRulesアプローチを使用する傾向があります。そのアプローチでは、無効なクラスとプロパティ、およびそれが無効である理由に関する情報を含むBrokenRulesオブジェクトを定義します。次に、共通の基本クラスで、オブジェクトに関する「間違った」すべてのリストを保持するリストを定義します。プロパティ(これも基本クラスにあります)IsValidは、現在違反しているルールがあるかどうかを示します。

これの利点は、オブジェクトの状態にいくつかの問題がある可能性があることです。ユーザーが問題の修正を求められている場合(つまり、このオブジェクトがUIから設定されている場合)、すべての問題のリストを提供することで、ユーザーは1つのエラーを修正して、別のエラーがあると言われるだけでなく、一度に修正できます。そしてもう一つ。等。

于 2009-08-26T23:07:05.920 に答える
0

このアプローチには何の問題もありません。コンストラクター内でこれに対してメソッドを呼び出すことができます。プロパティセッター/ゲッターは、メソッド呼び出しの単なる構文糖衣です。

于 2009-08-26T23:03:23.260 に答える
0

電子メールアドレスが設定されている場合、検証が行われます。メールアドレスは後で再設定される可能性があるため、これが必要な場所です。

コンストラクターで検証も呼び出した場合は、余分な冗長な検証呼び出しを行うことになります(1回は構築時に、もう1回はコンストラクターに電子メールアドレスが設定されている場合)。

于 2009-08-26T23:04:45.503 に答える