使用自定义比较委托

时间:2015-10-06 19:59:26

标签: c# linq generics delegates

我有一种情况,我需要一个泛型方法,我可以传递两个类型为T的集合以及一个比较两个集合的委托,如果集合1中的每个元素在集合2中具有相同的元素,则返回true,甚至如果它们不在集合的同一索引中。我的意思是"平等"由代表处理。我最初的想法是,如果集合的长度不同,则返回false,否则将它们排序,然后将它们比作并行数组。然后我突然意识到,我不能在没有共享接口的类型的情况下对泛型类型的集合进行排序。所以现在我认为LINQ表达式可能会成功,但我无法想到如何编写它。考虑一下我目前的代码:

private static bool HasSameCollectionItems<T>(ICollection<T> left, ICollection<T> right, Func<T, T, bool> func)
{
    if (left.Count != right.Count)
    {
        return false;
    }

    foreach (var item in left)
    {
        bool leftItemIsInRightCollection = ??? MAGIC ???

        if (!leftItemIsInRightCollection)
        {
            return false;
        }
    }

    return true;
}

我想用LINQ表达式替换??? MAGIC ???以查看item是否为&#34;等于&#34;使用传入的委托rightfunc中的元素。这甚至可能吗?

注意:由于我不想打扰到这里的原因,阻止IEquatable或覆盖Equals方法不是一个选项。

2 个答案:

答案 0 :(得分:0)

看起来你想要.All().Any()方法(第一种方法检查所有元素满足条件第二只检查是否存在这样的元素):

bool leftItemIsInRightCollection = right.Any(rItem => func(item, rItem));

此外,我还要将您的代码重构为:

    private static bool HasSameCollectionItems<T>(ICollection<T> left, ICollection<T> right, Func<T, T, bool> func)
    {
        return left.Count == right.Count && left.All(LI => right.Any(RI => func(LI, RI)));
    }

答案 1 :(得分:0)

以下工作通过检查left中是否有right之内的元素。

如果您坚持让代表确定平等,则可以使用here中的FuncEqualityComparer。 (请注意,您还必须提供Object.GetHashCode

的实现
private static bool HasSameCollectionItems<T>(ICollection<T> left, ICollection<T> right,  IEqualityComparer<T> comparer)
{
    if (left.Count != right.Count) return false;

    return !left.Except(right, comparer).Any();
}