このようなクラスがあります
_public class TestData
{
public string Name {get;set;}
public string type {get;set;}
public List<string> Members = new List<string>();
public void AddMembers(string[] members)
{
Members.AddRange(members);
}
}
_
このクラスのインスタンスを互いに直接比較して、それらがまったく同じであることがわかるかどうかを知りたいですか?メカニズムは何ですか?私はif(testData1 == testData2) //Do Something
のようなものを探しています。そうでない場合は、どうすればよいですか?
IEquatable<T>
クラスのインターフェース。これにより、等価ロジックを定義できます。実際には、Equals
メソッドもオーバーライドする必要があります。
public class TestData : IEquatable<TestData>
{
public string Name {get;set;}
public string type {get;set;}
public List<string> Members = new List<string>();
public void AddMembers(string[] members)
{
Members.AddRange(members);
}
// Overriding Equals member method, which will call the IEquatable implementation
// if appropriate.
public override bool Equals( Object obj )
{
var other = obj as TestData;
if( other == null ) return false;
return Equals (other);
}
public override int GetHashCode()
{
// Provide own implementation
}
// This is the method that must be implemented to conform to the
// IEquatable contract
public bool Equals( TestData other )
{
if( other == null )
{
return false;
}
if( ReferenceEquals (this, other) )
{
return true;
}
// You can also use a specific StringComparer instead of EqualityComparer<string>
// Check out the specific implementations (StringComparer.CurrentCulture, e.a.).
if( EqualityComparer<string>.Default.Compare (Name, other.Name) == false )
{
return false;
}
...
// To compare the members array, you could perhaps use the
// [SequenceEquals][2] method. But, be aware that [] {"a", "b"} will not
// be considerd equal as [] {"b", "a"}
return true;
}
}
参照タイプT
のオブジェクトを相互に比較するには、3つの方法があります。
object.Equals
メソッドを使用IEquatable<T>.Equals
の実装あり(IEquatable<T>
を実装する型のみ)==
さらに、これらの各ケースには2つの可能性があります。
T
(またはT
の他のベース)object
です絶対に知っておくべきルールは次のとおりです。
Equals
とoperator==
の両方のデフォルトは、参照の等価性をテストすることですEquals
の実装は、比較されるオブジェクトの静的タイプが何であっても正しく機能しますIEquatable<T>.Equals
は常にobject.Equals
と同じように動作する必要がありますが、オブジェクトの静的タイプがT
の場合、パフォーマンスはわずかに向上しますそれで、実際にこれはすべてどういう意味ですか?
経験則として、Equals
を使用して等価性を確認し(必要に応じてobject.Equals
を上書き)、IEquatable<T>
も実装して、パフォーマンスをわずかに向上させる必要があります。この場合、object.Equals
はIEquatable<T>.Equals
として実装する必要があります。
特定の型(System.String
など)の場合、operator==
を使用することもできますが、「多態的な比較」を行わないように注意する必要があります。一方、Equals
メソッドは、そのような比較を行っても正しく機能します。
ポリモーフィック比較の例と、なぜそれが問題になるのか here をご覧ください。
最後に、object.Equals
をオーバーライドする場合は、それに応じてobject.GetHashCode
もオーバーライドする必要があることを忘れないでください。
これを行う1つの方法は、IEquatable<T>
を実装することです
public class TestData : IEquatable<TestData>
{
public string Name {get;set;}
public string type {get;set;}
public List<string> Members = new List<string>();
public void AddMembers(string[] members)
{
Members.AddRange(members);
}
public bool Equals(TestData other)
{
if (this.Name != other.Name) return false;
if (this.type != other.type) return false;
// TODO: Compare Members and return false if not the same
return true;
}
}
if (testData1.Equals(testData2))
// classes are the same
Equals(object)メソッドを(System.Objectから)オーバーライドすることもできます。これを行う場合は、GetHashCodeもオーバーライドする必要があります ここを参照
まず第一に、平等を定義することは困難であり、平等があなたにとって何を意味するかについてあなただけが定義できます
ここに議論と答えがあります
ここには多くの良い答えがありますが、比較を次のように機能させたい場合に備えて
if(testData1 == testData2) // DoSomething
equals関数を使用する代わりに、==および!=演算子をオーバーライドできます。
public static bool operator == (TestData left, TestData right)
{
bool comparison = true; //Make the desired comparison
return comparison;
}
public static bool operator != (TestData left, TestData right)
{
return !(left == right);
}
Equalsメソッドをオーバーライドして、その中で手動でオブジェクトを比較できます
Equals()と演算子== のオーバーロードのガイドラインもご覧ください。
オブジェクトAをオブジェクトBと等しくするルールを定義してから、このタイプのEquals演算子をオーバーライドする必要があります。
http://msdn.Microsoft.com/en-us/library/ms173147(v = vs.80).aspx
IEquatable<T> interface
を実装します。これは、インスタンスの等価性を判断するための型固有のメソッドを作成するために値型またはクラスが実装する一般化されたメソッドを定義します。詳細はこちら: