tak*_*krl 31 .net c# generics comparison iequalitycomparer
假设我有一个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)
...提供与使用o1.Equals(o2)
所有可能情况相同的结果?
(作为旁注,这是否意味着我还需要使用任何特殊的通用约束<T>
?)
Dan*_*rth 42
它应该是相同的,但不能保证,因为它取决于类型的实现细节T
.
说明:
如果没有约束T
,o1.Equals(o2)将调用Object.Equals
,即使是T
implements IEquatable<T>
.
EqualityComparer<T>.Default
但是,只会使用Object.Equals
,如果T
没有实现IEquatable<T>
.如果它确实实现了该接口,则使用IEquatable<T>.Equals
.
只要T
执行Object.Equals
刚刚调用IEquatable<T>.Equals
的结果是一样的.但在以下示例中,结果不一样:
public class MyObject : IEquatable<MyObject>
{
public int ID {get;set;}
public string Name {get;set;}
public override bool Equals(object o)
{
var other = o as MyObject;
return other == null ? false : other.ID == ID;
}
public bool Equals(MyObject o)
{
return o.Name == Name;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,实现这样的类没有任何意义.但是如果实施者MyObject
只是忘了覆盖,你就会遇到同样的问题Object.Equals
.
结论:
使用EqualityComparer<T>.Default
是一种很好的方法,因为您不需要支持错误的对象!
归档时间: |
|
查看次数: |
16330 次 |
最近记录: |