我想从列表中获取不同的对象.我试图实施,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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我List的Message对象:
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());
Run Code Online (Sandbox Code Playgroud)
当我调用该Distinct()方法时,元素的数量collection是相同的.
Mat*_*gen 13
试试这个:
var distinct = collection.Distinct(new MessageComparer());
Run Code Online (Sandbox Code Playgroud)
然后distinct在那之后使用任何东西.
看起来你忘记了它的不变性IEnumerable<>.LINQ方法都没有实际更改原始变量.相反,它们返回IEnuerable<T>包含表达式结果的s.例如,让我们考虑List<string> original一下内容的简单{ "a", "a", "b", "c" }.
现在,让我们打电话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>作为参数.因此,他们没有实施原始清单的概念.您可以通过扩展方法传递a 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" }:
Run Code Online (Sandbox Code Playgroud)
小智 5
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();
}
}
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请参阅此链接:
http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html