我有2个名单:
list1<a>
list2<b>
我想根据a和b中存在的属性合并这两个没有重复的列表。
为此,我必须重写方法Equals和GetHashCode。
public override bool Equals(object otherInstance)
{
MyClass instance = otherInstance as MyClass ;
return (instance != null) ? GetGuid.Equals(instance .GetGuid) : false;
}
public override int GetHashCode()
{
return GetGuid.GetHashCode();
}
但是,我不能从公共基类继承A类和B类,因为它们已经使用C#扩展了其他类,并且多重继承无效。
有什么想法吗?
答案 0 :(得分:3)
有很多方法可以完成这项工作。我会采取捷径。如果您使用.Net 4.0及更高版本,这应该可以使用,如果没有,请发表评论我会更新我的答案。
List<Class1> list1 = new List<Class1>();
list1.Add(new Class1());
List<Class2> list2 = new List<Class2>();
list2.Add(new Class2());
var unionList = list1.Cast<object>()
.Union(list2.Cast<object>(), new DynamicComparer())
.ToList();
internal class DynamicComparer : IEqualityComparer<object>
{
public new bool Equals(object x, object y)
{
dynamic dx = x;
dynamic dy = y;
return dx.Guid == dy.Guid;
}
public int GetHashCode(object obj)
{
dynamic dobj = obj;
return dobj.Guid.GetHashCode();
}
}
internal class Class1
{
public Guid Guid { get; set; }
}
internal class Class2
{
public Guid Guid { get; set; }
}
由于我不知道您如何实施GetHashCode
和Equals
,我只举了一个例子。这应该让你知道如何开始。
如何运作:我们正在使用IEqualityComparer<T>
界面来完成工作,用于实现自定义比较规则以查找对象相等性。但问题是我们没有Class1
和Class2
的公共接口或基类,只能通过System.Object
将其表示为常见,因此我们实现了IEqualityComparer<object>
。
然后Equals
的实现非常简单,它只是将参数转换为dynamic,它利用了.Net4.0的动态特性。然后简单地动态比较属性或字段(没有编译时失败)在这种情况下我们比较Guid
属性和那就是全部。
值得注意的是,如果属性在运行时而不是编译时存在,则可能会失败。
希望这有帮助。
答案 1 :(得分:1)
这里有几个不错的选择。虽然C#不支持多重继承,但它确实支持一些非常方便的接口。您可以使用IComparable或IEquatable手动滚动您自己的解决方案,或使用LINQ Distinct方法。
另一种选择是使用LINQ Distinct并传递IEqualityComparer。
让A和B实现包含Prop的公共接口。然后:
class MyClassComparer<T> : IEqualityComparer<MyClass>
{
public bool Equals(object otherInstance)
{
MyClass instance = otherInstance as MyClass ;
return (instance != null) ? GetGuid.Equals(instance .GetGuid) : false;
}
public int GetHashCode()
{
return GetGuid.GetHashCode();
}
}
}
listA.AddRange(listB); //Need to be List<ICommonInterface> Common Interface
var distinctList = listA.Distinct(new MyClassComparer<T>());