3

関連するプライベートフィールドを実際に設定して他のいくつかのことを行う前に、値が変更されたかどうかを確認する複合コントロールのプロパティがあります。

ただし、ステートメントを評価していないようです。

プロパティのコードは次のとおりです。

public T SearchCriteria
        {
            get
            {
                return mySearchCriteria;
            }
            set
            {
                if (value != mySearchCriteria)
                {
                    mySearchCriteria = value;
                    EnsureChildControls();
                    SearchGridParser parser = SearchGridParserFactory.GetParser(this.Type);
                    parser.SetSearchPanelControls<T>(this.mySearchCriteria, ref mySearchParametersPanel);
                    GridView.PageIndex = 0;
                }
            }
        }

コードをステップ実行しましたが、「value!= mySearchCriteria」に到達するたびに、falseと評価され、ifステートメント内のコードをスキップします。実際、「value == mySearchCriteria」に変更しても、これは実行されます。評価方法に関係なく、完全にスキップすると!

なに?

チェックの引数の順序を変更し、object.Equals()を使用してみましたが、これらの変更のいずれも違いはありません。

Equals、!=、==およびGetHashCodeをオーバーライドしました。

コード内には、これらのオブジェクトタイプに「==」と「!=」を問題なく使用している場所が他にもあるので、オーバーライドが正しく機能していることがわかります。

問題は、これがオーバーライドされたメソッドにヒットすることさえないということです。"=="、 "!="、 "Equals"、 "GetHashCode"にブレークを入れましたが、 "value!= mySearchCriteria"ステートメントが評価されているときに、これらはいずれも呼び出されていません。

それはそれがそれを評価することを完全にスキップするようなものです。

4

1 に答える 1

4

ジェネリック型の間で == を使用することは、ほとんどの場合、悪い考えです。演算子はoverriddenではなくオーバーロードれるため、実際の型に == 演算子があっても、コンパイラはそれを認識しません。==(つまり、「オーバーライド」したというあなたの主張!=は既に間違っています。これらの演算子をオーバーロードしています。この違いは非常に重要であるため、必ず理解する必要があります。)

あなたが書くとき:

コード内には、これらのオブジェクト タイプに対して "==" と "!=" を問題なく使用している場所が他にもあるため、オーバーライドが正しく機能していることがわかります。

これらの領域は一般的なコードではないと思われます...それらは、コンパイラがどの型が比較されているかを知っている場所であるため、オーバーロードを使用することを知っています。これは、コンパイラが== に何を使用すればよいかわからない一般的な状況とは大きく異なるため、参照 ID にフォールバックします。

の一般的な制約があるwhere T : classか、コードがまったくコンパイルされないと仮定しますが、 の実際の型によって提供されるオーバーロードを使用する代わりに、参照比較を実行するだけですT

EqualityComparer.Default<T>.Equals(value, mySearchCriteria)インクルードのオーバーライドされた実装をEquals使用するために使用しますIEquatable<T>

于 2010-11-08T15:29:08.137 に答える