我想从列表中获得不同的对象。我试图实现IEqualityComparer
,但没有成功。请检查我的代码,并给我一个IEqualityComparer
的解释。
public class Message
{
public int x { get; set; }
public string y { get; set; }
public string z { get; set; }
public string w { get; set; }
}
public class MessageComparer : IEqualityComparer<Message>
{
public bool Equals(Message x, Message y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
if (x.x == y.x && x.y == y.y && x.z == y.z && x.w == y.w)
{
return true;
}
return false;
}
public int GetHashCode(Message number)
{
// if (Object.ReferenceEquals(number, null)) return 0;
int hashX = number.x.GetHashCode();
int hashY = number.y == null ? 0 : number.y.GetHashCode();
int hashZ = number.z == null ? 0 : number.z.GetHashCode();
int hashW = number.w == null ? 0 : number.w.GetHashCode();
return hashX ^ hashY ^ hashZ ^ hashW;
}
}
这是我的带有Message
对象的List
:
Message m1 = new Message();
m1.x = 1;
m1.y = "A";
m1.z = "B";
m1.w = "C";
Message m2 = new Message();
m2.x = 1;
m2.y = "A";
m2.z = "B";
m2.w = "C";
Message m3 = new Message();
m3.x = 1;
m3.y = "A";
m3.z = "B";
m3.w = "C";
Message m4 = new Message();
m4.x = 2;
m4.y = "A";
m4.z = "B";
m4.w = "C";
Message m5 = new Message();
m5.x = 3;
m5.y = "W";
m5.z = "D";
m5.w = "C";
Message m6 = new Message();
m6.x = 4;
m6.y = "S";
m6.z = "F";
m6.w = "R";
List<Message> collection = new List<Message>();
collection.Add(m1);
collection.Add(m2);
collection.Add(m3);
collection.Add(m4);
collection.Add(m5);
collection.Distinct(new MessageComparer());
当我调用Distinct()
方法时,collection
中的元素数量是相同的。
发布于 2014-07-24 10:22:35
试试这个:
var distinct = collection.Distinct(new MessageComparer());
然后在那之后的任何事情上使用distinct
。
看起来您忘记了IEnumerable<>
的不可变特性。没有一个LINQ方法实际更改了原始变量。相反,它们返回包含表达式结果的IEnuerable<T>
s。例如,让我们考虑一个内容为{ "a", "a", "b", "c" }
的简单List<string> original
。
现在,让我们调用original.Add("d");
。该方法没有返回值(它是void
)。但是,如果我们打印出original
的内容,我们将看到{ "a", "a", "b", "c", "d" }
。
另一方面,现在让我们调用original.Skip(1)
。此方法确实有一个返回值,即IEnumerable<string>
类型之一。它是一个LINQ表达式,不会对原始集合执行任何副作用操作。因此,如果我们调用它并查看original
,我们将看到{ "a", "a", "b", "c", "d" }
。但是,该方法的结果将是{ "a", "b", "c", "d" }
。如您所见,结果跳过了一个元素。
这是因为LINQ方法接受IEnumerable<T>
作为参数。因此,他们对原始列表的实现没有概念。您可以通过扩展方法传递一个ReadOnlyCollection
,而他们仍然能够通过它进行计算。因此,它们不能更改原始集合,因为原始集合可以以任意数量的方式编写。
所有这些,但以表格的形式。每行都以原始{ "a", "a", "b", "c" }
开头
Context Example function Immutable? Returned Value Collection after calling
Collection Add("d") No (void) { "a", "a", "b", "c", "d" }:
LINQ Skip(1) Yes { "a", "b", "c" } { "a", "a", "b", "c" }:
发布于 2016-09-09 11:53:14
IEqualityComparer
是一个用来判断一个对象是否相等的接口。我们将在一个示例中看到这一点,其中我们必须在集合中找到不同的对象。此接口将实现方法Equals(T obj1,T obj2)
。
abstract public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { set; get; }
}
public enum SortType
{
ByID,
BySalary
}
public class EmployeeDistinctEquality : IEqualityComparer<Employee>
{
public EmployeeDistinctEquality()
{
}
public bool Equals(Employee x, Employee y)
{
if (x == null && y == null)
return true;
else if (x == null || y == null)
return false;
else if (x.Id == y.Id)
return true;
else
return false;
}
public int GetHashCode(Employee obj)
{
return obj.Id.GetHashCode();
}
}
有关更多详细信息,请参阅此链接:
http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html
发布于 2014-07-24 10:23:57
你不需要实现IEqualityComparer
:
public class Message
{
protected bool Equals(Message other)
{
return string.Equals(x, other.x) && string.Equals(y, other.y) && string.Equals(z, other.z) && string.Equals(w, other.w);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Message) obj);
}
public override int GetHashCode()
{
unchecked //Ignores overflows that can (should) occur
{
var hashCode = x;
hashCode = (hashCode*397) ^ (y != null ? y.GetHashCode() : 0);
hashCode = (hashCode*397) ^ (z != null ? z.GetHashCode() : 0);
hashCode = (hashCode*397) ^ (w != null ? w.GetHashCode() : 0);
return hashCode;
}
}
public int x { get; set; }
public string y { get; set; }
public string z { get; set; }
public string w { get; set; }
}
https://stackoverflow.com/questions/24924071
复制相似问题