152

C# に 2 つのオブジェクトがあり、それがブール型なのか他の型なのかわかりません。ただし、これらの C# を比較しようとすると、正しい答えが得られません。私は VB.NET で同じコードを試してみました。

解決策があれば、これを修正する方法を教えてもらえますか?

C#:

object a = true;
object b = true;
object c = false;
if (a == b) c = true;
MessageBox.Show(c.ToString()); //Outputs False !!

VB.NET:

Dim a As Object = True
Dim b As Object = True
Dim c As Object = False
If (a = b) Then c = True
MessageBox.Show(c.ToString()) '// Outputs True
4

4 に答える 4

168

C# では、==演算子 (参照型の式に適用された場合) は、オーバーロードされていない限り、参照の等価性チェックを実行します。ボクシング変換の結果である 2 つの参照を比較しているため、これらは別個の参照です。

編集: をオーバーロードする型を使用すると、異なる動作を得ることができますが、それは式のコンパイル時==の型に基づいています。たとえば、以下を提供します):string==(string, string

string x = new string("foo".ToCharArray());
string y = new string("foo".ToCharArray());
Console.WriteLine(x == y); // True
Console.WriteLine((object) x == (object) y); // False

ここで、最初の比較はオーバーロードされた演算子を使用していますが、2 番目は「デフォルト」の参照比較を使用しています。

VB では、=演算子はさらに多くの作業を行います。たとえば、テキストの比較方法に影響を与える可能性があるためobject.Equals(x, y)、を使用することと同等ではありません。Option Compare

基本的に、オペレーターは同じようには機能せず、同じように機能することを意図していません。

于 2013-02-12T16:38:57.070 に答える
79

C# の側面を説明する Jon の回答に加えて、VB の機能は次のとおりです。

VB withOption Strict Onでは、 による比較は= 常に値の等価性をテストし、参照の等価性をテストすることはありません。実際、 は .を定義していないため、Option Strict On切り替えるとコードはコンパイルされません。このオプションは常にオンにしておく必要があります。ハエトリグサよりも効果的にバグをキャッチします (ただし、特定のケースでは、この緩い動作が実際には正しいことを行います)。1System.ObjectOperator=

実際、 を使用するとOption Strict On、VB は C# よりもさらに厳密に動作します。C# では、への呼び出しをトリガーするa == b SomeType.operator==(a, b)、存在しない場合は参照等価比較を呼び出します (これは を呼び出すことと同じですobject.ReferenceEquals(a, b))。

一方、VB では、比較a = b は常に等価演算子を呼び出します。2参照等価比較を使用する場合は、使用する必要がありますa Is b(これも と同じObject.ReferenceEquals(a, b)です)。


1)を使用することが悪い考えである理由を次に示しOption Strict Offます。私は .NET が公式にリリースされる前から数年前まで、ほぼ 10 年間 VB.NET を使用してきましたが、.NET が何をするのかまったくわかりませa = bOption Strict Off。ある種の等価比較を行いますが、正確に何が起こり、その理由はわかりません。ただし、 C# の機能よりも複雑dynamicです (十分に文書化された API に依存しているため)。MSDN の内容は次のとおりです。

強力な型付けOption Strict Onを提供し、データの損失を伴う意図しない型変換を防ぎ、遅延バインディングを禁止し、パフォーマンスを向上させるため、使用することを強くお勧めします。

2) Jon は 1 つの例外として文字列について言及しました。文字列では、後方互換性のために等値比較がさらにいくつかのことを行います。

于 2013-02-12T20:01:48.790 に答える
4

オブジェクト インスタンスは、演算子「==」と比較されません。メソッド「equals」を使用する必要があります。「==」演算子を使用すると、オブジェクトではなく参照が比較されます。

これを試して:

public class MyObject
{
    public MyObject(String v)
    {
        Value = v;
    }
    public String Value { get; set; }
}

MyObject a = new MyObject("a");
MyObject b = new MyObject("a");
if(a==b){
    Debug.WriteLine("a reference is equal to b reference");
}else{
    Debug.WriteLine("a reference is not equal to b reference");
}
if (a.Equals(b)) {
    Debug.WriteLine("a object is equal to b object");
} else {
    Debug.WriteLine("a object is not equal to b object");
}

結果:

a reference is not equal to b reference
a object is not equal to b object

今、これを試してください:

public class MyObject
{
    public MyObject(String v)
    {
        Value = v;
    }
    public String Value { get; set; }

    public bool Equals(MyObject o)
    {
        return (Value.CompareTo(o.Value)==0);
    }
}
MyObject a = new MyObject("a");
MyObject b = new MyObject("a");
if(a==b){
    Debug.WriteLine("a reference is equal to b reference");
}else{
    Debug.WriteLine("a reference is not equal to b reference");
}
if (a.Equals(b)) {
    Debug.WriteLine("a object is equal to b object");
} else {
    Debug.WriteLine("a object is not equal to b object");
}

結果:

a reference is not equal to b reference
a object is equal to b object
于 2013-02-12T16:40:16.443 に答える