我想了解应该使用IEqualityComparer<T>和IEquatable<T>应该使用的场景.两者的MSDN文档看起来非常相似.
我试图理解IEqualityComparer接口的GetHashCode方法的作用.
以下示例来自MSDN:
using System;
using System.Collections.Generic;
class Example {
static void Main() {
try {
BoxEqualityComparer boxEqC = new BoxEqualityComparer();
Dictionary<Box, String> boxes = new Dictionary<Box,
string>(boxEqC);
Box redBox = new Box(4, 3, 4);
Box blueBox = new Box(4, 3, 4);
boxes.Add(redBox, "red");
boxes.Add(blueBox, "blue");
Console.WriteLine(redBox.GetHashCode());
Console.WriteLine(blueBox.GetHashCode());
}
catch (ArgumentException argEx) {
Console.WriteLine(argEx.Message);
}
}
}
public class Box {
public Box(int h, int l, int w) {
this.Height = h;
this.Length = l;
this.Width = w;
}
public int …Run Code Online (Sandbox Code Playgroud) class Program
{
static void Main(string[] args)
{
List<Book> books = new List<Book>
{
new Book
{
Name="C# in Depth",
Authors = new List<Author>
{
new Author
{
FirstName = "Jon", LastName="Skeet"
},
new Author
{
FirstName = "Jon", LastName="Skeet"
},
}
},
new Book
{
Name="LINQ in Action",
Authors = new List<Author>
{
new Author
{
FirstName = "Fabrice", LastName="Marguerie"
},
new Author
{
FirstName = "Steve", LastName="Eichert"
},
new Author
{
FirstName = "Jim", LastName="Wooley"
},
}
}, …Run Code Online (Sandbox Code Playgroud) 我的数据库中有一些相同数字的铃声.我希望所有这些都没有重复.然后我创建了一个比较类来完成这项工作,但是函数的执行从函数中产生了很大的延迟而没有明显的,从0.6秒到3.2秒!
我做得对吗还是我必须使用其他方法?
reg.AddRange(
(from a in this.dataContext.reglements
join b in this.dataContext.Clients on a.Id_client equals b.Id
where a.date_v <= datefin && a.date_v >= datedeb
where a.Id_client == b.Id
orderby a.date_v descending
select new Class_reglement
{
nom = b.Nom,
code = b.code,
Numf = a.Numf,
})
.AsEnumerable()
.Distinct(new Compare())
.ToList());
class Compare : IEqualityComparer<Class_reglement>
{
public bool Equals(Class_reglement x, Class_reglement y)
{
if (x.Numf == y.Numf)
{
return true;
}
else { return false; }
}
public int GetHashCode(Class_reglement codeh)
{
return …Run Code Online (Sandbox Code Playgroud) 是否有使用的默认IEqualityComparer<T>实现ReferenceEquals?
EqualityComparer<T>.Default使用ObjectComparer,它使用object.Equals().在我的例子中,对象已经实现IEquatable<T>,我需要忽略并仅通过对象的引用进行比较.
我碰巧看到了一些代码,其中这个人将lambda表达式传递给ArrayList.Sort(这里是IComparer)或IEnumerable.SequenceEqual(IEnumerable列表,IEqualityComparer here),其中需要IComparer或IEqualityComparer.
我不能确定我是否看过它,或者我只是在做梦.我似乎无法在这些集合中找到任何接受Func <>或其方法签名中的委托的扩展.
有这样的过载/扩展方法吗?或者,如果没有,是否有可能像这样捣乱并传递一个算法(读委托),其中预期单方法接口?
更新 谢谢大家.那正是我所想.我一定是在做梦.我知道如何编写转换.我只是不确定我是否见过这样的东西,或者只是觉得我已经看过了.
又一次更新 看,在这里,我找到了一个这样的实例.毕竟我并没有做梦.看看这家伙在这做什么.是什么赋予了?
这是另一个更新:
好的,我明白了.那家伙正在使用Comparison<T>超载.尼斯.很好,但完全容易误导你.不过很好.谢谢.
linq ienumerable extension-methods icomparer iequalitycomparer
我注意到这两个接口,以及几个相关的类,已经在.NET 4中添加了.它们对我来说似乎有点多余; 我已经阅读了几个关于它们的博客,但我仍然无法弄清楚它们在.NET 4之前解决了哪些棘手问题.
什么是使用IStructuralEquatable和IStructuralComparable?
我有一个L2E查询返回一些包含重复对象的数据.我需要删除那些重复的对象.基本上我应该假设如果他们的ID是相同的,那么对象是重复的.我试过了q.Distinct(),但仍然返回了重复的对象.然后我尝试实现自己的IEqualityComparer并将其传递给Distinct()方法.该方法失败,并带有以下文字:
LINQ to Entities无法识别方法'System.Linq.IQueryable
1[DAL.MyDOClass] Distinct[MyDOClass](System.Linq.IQueryable1 [DAL.MyDOClass],System.Collections.Generic.IEqualityComparer`1 [DAL.MyDOClass])'方法,并且此方法无法转换为商店表达式.
这是EqualityComparer的实现:
internal class MyDOClassComparer: EqualityComparer<MyDOClass>
{
public override bool Equals(MyDOClass x, MyDOClass y)
{
return x.Id == y.Id;
}
public override int GetHashCode(MyDOClass obj)
{
return obj == null ? 0 : obj.Id;
}
}
Run Code Online (Sandbox Code Playgroud)
那我该怎么写自己的IEqualityComparer呢?
我有这个
var n = ItemList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList();
n.AddRange(OtherList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList(););
Run Code Online (Sandbox Code Playgroud)
如果允许,我想这样做
n = n.Distinct((x, y) => x.Vchr == y.Vchr)).ToList();
Run Code Online (Sandbox Code Playgroud)
我尝试使用通用的LambdaComparer,但由于我使用的是匿名类型,因此没有类型与之关联.
"帮助我Obi Wan Kenobi,你是我唯一的希望"
假设我有一个MyClass<T>需要比较两个类型对象的泛型<T>.通常我会做......
void DoSomething(T o1, T o2)
{
if(o1.Equals(o2))
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
现在假设我MyClass<T>有一个支持传递自定义的构造函数IEqualityComparer<T>,类似于Dictionary<T>.在那种情况下,我需要做......
private IEqualityComparer<T> _comparer;
public MyClass() {}
public MyClass(IEqualityComparer<T> comparer)
{
_comparer = comparer;
}
void DoSomething(T o1, T o2)
{
if((_comparer != null && _comparer.Equals(o1, o2)) || (o1.Equals(o2)))
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
要删除这个冗长的if语句,_comparer如果使用常规构造函数,我可以默认使用'default comparer'.我搜索了类似的东西,typeof(T).GetDefaultComparer()却找不到类似的东西.
我找到了EqualityComparer<T>.Default,我可以用它吗?然后这个片段......
public MyClass()
{
_comparer = EqualityComparer<T>.Default;
}
void DoSomething(T o1, T o2)
{
if(_comparer.Equals(o1, o2))
{ …Run Code Online (Sandbox Code Playgroud) c# ×7
.net ×6
linq ×4
iequatable ×2
comparison ×1
distinct ×1
equality ×1
equals ×1
generics ×1
gethashcode ×1
icomparable ×1
icomparer ×1
ienumerable ×1
lambda ×1