Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IEqualityComparer重载的GroupJoin仅比较内部集合中的对象_C#_Lambda_Iequalitycomparer - Fatal编程技术网

C# IEqualityComparer重载的GroupJoin仅比较内部集合中的对象

C# IEqualityComparer重载的GroupJoin仅比较内部集合中的对象,c#,lambda,iequalitycomparer,C#,Lambda,Iequalitycomparer,在与客户IEqualityComparer实现组联接时,我遇到了一些奇怪的行为 下面的代码演示了我遇到的问题 List<String> inner = new List<string>() { "i1", "i2" }; List<String> outer = new List<string>() { "o1", "o2" }; var grouped = outer.GroupJoin(inner, i => i, o=> o,

在与客户IEqualityComparer实现组联接时,我遇到了一些奇怪的行为

下面的代码演示了我遇到的问题

List<String> inner = new List<string>() { "i1", "i2" };
List<String> outer = new List<string>() { "o1", "o2" };

var grouped = outer.GroupJoin(inner, i => i, o=> o, (inKey, outCollection) => new {Key = inKey, List = outCollection},
        new EqualityComparer<string>((i, o) => i == o)).ToList();

GroupJoin
操作首先需要构建一个查找-基本上是从
internal
中的每个投影键到使用该键的
internal
元素。这就是为什么要传递
内部
值。这在“当请求第一个结果时”方面是惰性的,但此时它将消耗整个
internal

然后,一旦建立了查找,
outer
流式传输,一次传输一个元素。此时,应要求自定义相等比较器比较内部键和外部键。事实上,当我将日志添加到您的比较器(我已重命名该比较器以避免与框架
EqualityComparer
type冲突)时,我看到:

using System;
using System.Linq;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        List<String> inner = new List<string>() { "i1", "i2" };
        List<String> outer = new List<string>() { "o1", "o2" };

        outer.GroupJoin(inner, i => i, o=> o,
            (inKey, outCollection) => new {Key = inKey, List = outCollection},
            new CustomEqualityComparer<string>((i, o) => i == o)).ToList();
    }
}

public class CustomEqualityComparer<T> : IEqualityComparer<T>
{
    public CustomEqualityComparer(Func<T, T, bool> cmp)
    {
        this.cmp = cmp;
    }
    public bool Equals(T x, T y)
    {
        Console.WriteLine("Comparing {0} and {1}", x, y);
        return cmp(x, y);
    }

    public int GetHashCode(T obj)
    {
        // Always return 0 so that the function is called
        return 0;
    }

    public Func<T, T, bool> cmp { get; set; }
}

现在,这不是
GroupJoin
唯一可能的实现,但这是一个相当明显的实现。有关详细信息,请参见我的
GroupJoin

您的文档链接是Queryable.GroupJoin,但您正在调用Enumerable.GroupJoin。如果您使用与参数名称相反的
outer
inner
,则会让人感到困惑。seehttps://msdn.microsoft.com/en-us/library/vstudio/bb535047(v=vs.100)。aspx@Jon-谢谢!我改变了名称以使其更清晰,并查看了正确的文档页面,但我没有看到IQueryable版本和IEnumerable之间的任何区别。在代码的真实版本中,如果在
IQueryable
上调用它,那么在IQueryable上调用它的结果是相同的,这很有趣,因为查询提供程序可能能够识别自定义比较器并将其转换为另一个表示形式(例如SQL)。。。或者它可能不会(包括将所有数据带到本地)。太棒了!因此,在将内部元素添加到查找表时,首先使用比较器检查内部元素是否唯一,然后将外部元素排序到组中。这解释了我在这个测试中看到的情况,但意味着我在实际实现中有一个bug。谢谢你的帮助here@CurlyPaul:它不会检查内部元素是否有唯一的键-它们可能没有。关键是创建一个匹配每个键的内部元素列表。毕竟,这是团队的一部分:)对,明白了。我想我需要另一个解决方案,因为这对我来说是行不通的,但我现在对它的工作原理有了更好的理解
using System;
using System.Linq;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        List<String> inner = new List<string>() { "i1", "i2" };
        List<String> outer = new List<string>() { "o1", "o2" };

        outer.GroupJoin(inner, i => i, o=> o,
            (inKey, outCollection) => new {Key = inKey, List = outCollection},
            new CustomEqualityComparer<string>((i, o) => i == o)).ToList();
    }
}

public class CustomEqualityComparer<T> : IEqualityComparer<T>
{
    public CustomEqualityComparer(Func<T, T, bool> cmp)
    {
        this.cmp = cmp;
    }
    public bool Equals(T x, T y)
    {
        Console.WriteLine("Comparing {0} and {1}", x, y);
        return cmp(x, y);
    }

    public int GetHashCode(T obj)
    {
        // Always return 0 so that the function is called
        return 0;
    }

    public Func<T, T, bool> cmp { get; set; }
}
Comparing i1 and i2
Comparing i1 and i2
Comparing i1 and i2
Comparing i2 and o1
Comparing i1 and o1
Comparing i2 and o2
Comparing i1 and o2