Сравнение двух экземпляров класса
у меня есть класс такой
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 и если нет, то как это сделать?
7 ответов
вы должны использовать тег 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 можно сравнить друг с другом:
- С
object.Equalsметод - с осуществлением
IEquatable<T>.Equals(только для типов, которые реализуютIEquatable<T>) - с оператором сравнения
==
кроме того, есть две возможности для каждого из этих случаев:
- статический тип сравниваемых объектов
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==, хотя вы должны быть осторожны, чтобы не сделать "полиморфных сравнения". The Equals методы, с другой стороны, будут работать правильно, даже если вы делаете такие сравнения.
вы можете увидеть пример полиморфного сравнения и почему это может быть проблемой здесь.
наконец, никогда не забывайте, что если вы переопределяете object.Equals вы также должны переопределить object.GetHashCode соответственно.
один из способов сделать это-реализовать 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) (from System.Object), если вы это сделаете, вы также должны переопределить GetHashCode посмотреть здесь
вы можете переопределить метод equals и внутри него вручную сравнить объекты
посмотрите рекомендации по перегрузке Equals () и Operator ==
вам нужно будет определить правила, которые делают объект A равным объекту B, а затем переопределить оператор Equals для этого типа.
http://msdn.microsoft.com/en-us/library/ms173147 (v=против 80).aspx
прежде всего равенство трудно определить, и только вы можете определить, что означает равенство для вас
- означает ли это, что члены имеют одинаковое значение
- или они указывают на одно и то же место.
вот Обсуждение и ответ здесь
что такое "лучшая практика" для сравнения двух экземпляров ссылочного типа?
реализовать IEquatable<T> interface. Это определяет обобщенный метод, реализуемый типом значения или классом для создания специфичного для типа метода определения равенства экземпляров. Более подробная информация здесь: