c# - 如何比较两个实现相同接口的不同类是否相等?
问题描述
public interface IMyType{
int Val1 {get; set;}
int Val2 {get; set;}
}
public class ImplA : IMyType{
public int Val1 {get; set;}
public int Val2 {get; set;}
public string Name {get; set;}
}
public class ImplB : IMyType{
public int Val1 {get; set;}
public int Val2 {get; set;}
public int Age {get; set;}
}
List<IMyType> myTypes = new List<IMyType>();
myTypes.Add(new ImplA(){ Val1 = 100, Val2 = 200, Name ="John"});
myTypes.Add(new ImplA(){ Val1 = 500, Val2 = 600, Name ="Steve"});
IMyType t = new ImplB(){ Val1 = 100, Val2 = 200, Age =30});
bool exists = myTypes.Contains(t); //returns false because types are different
它比较实现类型是否相等并导致“错误”是有道理的,但是有没有办法进行相等并包含这样它忽略实现类型而只比较接口属性是否相等?(在这个例子中它会返回真,因为 Val1 和 Val2 是相等的)
解决方案
如果你不能覆盖Equals
你的类型的自定义,你总是可以为接口类型定义一个自定义的平等比较器。
using System:
using System.Collections.Generic;
// implements IEqualityComparer<IMyType>
// it's recommended to derive from EqualityComparer<T>
public class MyTypeComparer : EqualityComparer<IMyType>
{
public override int GetHashCode(IMyType obj){
return HashCode.Combine(obj.Val1, obj.Val2);
// or if System.HashCode is unavailable, something like
// return 37 ^ obj.Val1 ^ obj.Val2;
}
public override bool Equals(IMyType a, IMyType b) {
if (ReferenceEquals(a, b)) return true;
if (a is null || b is null) return false;
return a.Val1 == b.Val1 && a.Val2 == b.Val2;
}
}
然后使用Enumerable.Contains
接受一个IEqualityComparer<T>
而不是的扩展方法List<T>.Contains
using System;
using System.Linq;
using System.Collections.Generic;
var myTypes = new List<IMyType>();
myTypes.Add(new ImplA(){ Val1 = 100, Val2 = 200, Name = "John"});
myTypes.Add(new ImplA(){ Val1 = 500, Val2 = 600, Name = "Steve"});
IMyType t = new ImplB(){ Val1 = 100, Val2 = 200, Age = 30 };
bool exists = myTypes.Contains(t, new MyTypeComparer());
Console.WriteLine(exists); // true
有关示例,请参阅此SharpLab。
推荐阅读
- javascript - 如何安排渲染平面列表?
- css - 是否有一个 css 标签可以将 div 定位在其父级的特定嵌套深度?
- reactjs - 未找到具有指定模式的包:D:\a\r1\a\**\*.zip
- java - 为什么它不绘制图片 Jpanel
- actions-on-google - 无法通过显式调用调用 DialogFlow 代理
- c# - 将 foreach 循环中的 if-else 转换为 LINQ
- javascript - Javascript如何访问一个类中的一个类
- javascript - 需要帮助更新所选行的索引
- c# - await Task.FromResult 有什么好处吗?
- git - 如何告诉 git 在再次修改之前停止以 git status 显示文件?