Akr*_*rem 90 c# linq iequalitycomparer
我的数据库中有一些相同数字的铃声.我希望所有这些都没有重复.然后我创建了一个比较类来完成这项工作,但是函数的执行从函数中产生了很大的延迟而没有明显的,从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 0;
}
}
Run Code Online (Sandbox Code Playgroud)
Kon*_*lph 165
难怪,考虑到你的GetHashCode实现总是返回相同的值.Distinct依靠良好的哈希函数来高效工作.
当实现的类接口,你需要阅读的文件第一次,否则你不知道你应该执行哪一项合同.1
在你的代码,解决办法是转发GetHashCode到Class_reglement.Numf.GetHashCode并实施适当的存在.
除此之外,您的Equals方法充满了不必要的代码.它可以重写如下(相同的语义,¼代码,更可读):
public bool Equals(Class_reglement x, Class_reglement y)
{
return x.Numf == y.Numf;
}
Run Code Online (Sandbox Code Playgroud)
此外,ToList呼叫是不必要和耗时的:AddRange接受任何调用,因此不需要IEnumerable转换为a List.AsEnumerable在也这里多余的,因为处理结果AddRange无论如何都会导致此.
1实现代码而不知道它实际上做了什么称为货物崇拜编程.这是一种令人惊讶的普遍做法.它从根本上说是行不通的.
小智 46
试试这段代码:
public class GenericCompare<T> : IEqualityComparer<T> where T : class
{
private Func<T, object> _expr { get; set; }
public GenericCompare(Func<T, object> expr)
{
this._expr = expr;
}
public bool Equals(T x, T y)
{
var first = _expr.Invoke(x);
var sec = _expr.Invoke(y);
if (first != null && first.Equals(sec))
return true;
else
return false;
}
public int GetHashCode(T obj)
{
return obj.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
它的使用范例是
collection = collection
.Except(ExistedDataEles, new GenericCompare<DataEle>(x=>x.Id))
.ToList();
Run Code Online (Sandbox Code Playgroud)
如果您想要一个通用解决方案,根据该类的属性(充当键)为您的类创建一个 IEqualityComparer,请查看以下内容:
public class KeyBasedEqualityComparer<T, TKey> : IEqualityComparer<T>
{
private readonly Func<T, TKey> _keyGetter;
public KeyBasedEqualityComparer(Func<T, TKey> keyGetter)
{
if (default(T) == null)
{
_keyGetter = (x) => x == null ? default : keyGetter(x);
}
else
{
_keyGetter = keyGetter;
}
}
public bool Equals(T x, T y)
{
return EqualityComparer<TKey>.Default.Equals(_keyGetter(x), _keyGetter(y));
}
public int GetHashCode(T obj)
{
TKey key = _keyGetter(obj);
return key == null ? 0 : key.GetHashCode();
}
}
public static class KeyBasedEqualityComparer<T>
{
public static KeyBasedEqualityComparer<T, TKey> Create<TKey>(Func<T, TKey> keyGetter)
{
return new KeyBasedEqualityComparer<T, TKey>(keyGetter);
}
}
Run Code Online (Sandbox Code Playgroud)
为了获得更好的结构性能,没有任何装箱。
用法是这样的:
IEqualityComparer<Class_reglement> equalityComparer =
KeyBasedEqualityComparer<Class_reglement>.Create(x => x.Numf);
Run Code Online (Sandbox Code Playgroud)