Сравнение двух экземпляров класса
у меня есть класс такой
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
. Это определяет обобщенный метод, реализуемый типом значения или классом для создания специфичного для типа метода определения равенства экземпляров. Более подробная информация здесь: