質問

VisualStudio (Pro 2008) で、いくつかの矛盾した動作に気づき、その背後に何か論理的な理由があるのではないかと疑問に思いました。

WinForms プロジェクトで次の行を使用すると、

if(myComboBox.Items[i] == myObject)

オブジェクト型と MyObject 型を比較しているときに、「意図しない参照の可能性があります」というコンパイラ警告が表示されます。けっこうだ。

ただし、代わりにインターフェイスを使用して比較すると、次のようになります。

if(myComboBox.Items[i] == iMyInterface)

コンパイル警告は消えます。

これが発生する論理的な理由があるのか​​、それともインターフェイスの比較警告をチェックしないコンパイラの単なる成果物なのか、誰か考えられますか。何かご意見は?

編集 私の例では、コンボボックスはリストにバインドされていましたが、そのリストは次を使用して生成されました。 list<IMyInterface>.Cast<MyObject>().ToList<MyObject>()

それは、コンパイラーが IMyInterface のリストにバインドしていると仮定して静止しているだけのようです。

(オブジェクトとインターフェイスのメソッドは、無実のユーザーを保護するために変更されました)

役に立ちましたか?

解決

最初のサンプルのコンパイル警告は、クラスのカスタム == 演算子が無視され、参照が比較されるためです (意図したものではない可能性があるため、警告が表示されます)。

インターフェイス上で演算子をオーバーライドするように指定することはできないため、 いつも 参考比較になります。この警告は常に予期されるものであるため、警告は必要ありません。

== 演算子をオーバーライドする例を次に示します。

class Program
{
    static void Main(string[] args)
    {
        object t1 = new MyTest() { Key = 1 };
        MyTest t2 = new MyTest() { Key = 1 };

        Console.WriteLine((MyTest)t1 == t2); // Uses overriden == operator, returns true
        Console.WriteLine(t1 == t2); // Reference comparison, returns false
    }
}

public class MyTest
{
    public int Key { get; set; }

    public override bool Equals(object obj)
    {
        return this.Key == (obj as MyTest).Key;
    }

    public override int GetHashCode()
    {
        return this.Key.GetHashCode();
    }

    public static bool operator ==(MyTest t1, MyTest t2)
    {
        return t1.Equals(t2);
    }

    public static bool operator !=(MyTest t1, MyTest t2)
    {
        return !t1.Equals(t2);
    }

}

Key プロパティが等しい場合、MyTest クラスは等しいとみなされます。インターフェイスを作成する場合、カスタム == 演算子を含めるように指定することはできないため、比較は常に参照比較になります (したがって、サンプル コードの場合は false)。

他のヒント

ラゲルダレク

この警告が生成されるのは、比較する前に、項目を Items コレクションからコンボ ボックスにバインドされていた元の型にキャストし直す必要があるためです。そうしないと、コンパイラの警告に従って予期しない結果が得られる可能性があります。

以下に例を示します。

myComboBox.DataSource = Collection<Car>;

したがって、コンボボックスが次のコレクションにバインドされている場合、 オブジェクトを比較する前にキャストバックします。

if((car)myComboBox.Items[i] == thisCar)

そうすれば、警告は表示されないはずです。

もう 1 つの方法は次のとおりです。

using(myComboBox.Items[i] as car){
 if(myComboBox.Items[i] == thisCar)
}

お知らせ下さい。幸運を!記憶を頼りに話していますが、何もタイプミスしていないことを願います。:o)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top