联盟按内容列出

时间:2014-03-04 12:54:49

标签: c# linq collections

我有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#扩展了其他类,并且多重继承无效。

有什么想法吗?

2 个答案:

答案 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; }
}

由于我不知道您如何实施GetHashCodeEquals,我只举了一个例子。这应该让你知道如何开始。

如何运作:我们正在使用IEqualityComparer<T>界面来完成工作,用于实现自定义比较规则以查找对象相等性。但问题是我们没有Class1Class2的公共接口或基类,只能通过System.Object将其表示为常见,因此我们实现了IEqualityComparer<object>

然后Equals的实现非常简单,它只是将参数转换为dynamic,它利用了.Net4.0的动态特性。然后简单地动态比较属性或字段(没有编译时失败)在这种情况下我们比较Guid属性和那就是全部。

值得注意的是,如果属性在运行时而不是编译时存在,则可能会失败。

希望这有帮助。

答案 1 :(得分:1)

这里有几个不错的选择。虽然C#不支持多重继承,但它确实支持一些非常方便的接口。您可以使用IComparable或IEquatable手动滚动您自己的解决方案,或使用LINQ Distinct方法。

另一种选择是使用LINQ Distinct并传递IEqualityComparer。

让A和B实现包含Prop的公共接口。然后:

LINQ Distinct

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>());
相关问题