Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# 为linq联接创建自定义比较器的正确方法_C#_Linq_Join - Fatal编程技术网

C# 为linq联接创建自定义比较器的正确方法

C# 为linq联接创建自定义比较器的正确方法,c#,linq,join,C#,Linq,Join,我在创建用于linq.join的自定义比较器时遇到一些问题。 我不是linq方面的专家,所以我可能误解了连接函数的行为 这是我的密码。我想在这两个列表之间执行一个简单的连接: List<MyObj> operand1Data = new List<MyObj>() { new MyObj() { Var = "1var1", Year = 0 }, new MyObj() { Var = "1var2", Year = 2018 }, }; List&l

我在创建用于linq.join的自定义比较器时遇到一些问题。 我不是linq方面的专家,所以我可能误解了连接函数的行为

这是我的密码。我想在这两个列表之间执行一个简单的连接:

List<MyObj> operand1Data = new List<MyObj>()
{
    new MyObj() { Var = "1var1", Year = 0 },
    new MyObj() { Var = "1var2", Year = 2018 },
};

List<MyObj> operand2Data = new List<MyObj>()
{
    new MyObj() { Var = "2var1", Year = 2018 },
    new MyObj() { Var = "2var2", Year = 2019 },
    new MyObj() { Var = "2var3", Year = 2020 },
};

var result= operand1Data.Join(operand2Data, x => x.Year, y => y.Year, (x, y) => x.Var + y.Var, new TestComparer()).ToList();
我所期望的是:

"1var12var1"
"1var12var2"
"1var12var3"
"1var22var1"

我错过了什么?有人能帮我修一下吗?谢谢您的帮助。

我已经尝试了您的代码,我想LINQ Join有一个默认过滤器,它在自定义
IEqualityComparer
之前应用

Equals(x,y)
中有一个日志,这就是我得到的:

看到了吗?只有一个“零”相等检查

因此,我的建议是将linq查询语法与交叉连接一起使用,然后根据
中的
条件过滤元素:

var result = from o1 in operand1Data
             from o2 in operand2Data
             where o1.Year == 0 || o2.Year == 0 || o1.Year == o2.Year
             select o1.Var + o2.Var;
结果正是您想要的:


希望这有帮助

谢谢你的帮助。在执行相同的测试时,我得出结论,“join”操作在第二个列表的元素之间创建了一个“相等映射”,以减少它必须对第一个列表的元素执行的测试数量。这可以解释这种行为:因为2020不等于第二个列表中的任何其他元素,并且在第一个列表中等于0,所以它假设0也不等于第二个列表中的其他元素。我找不到任何关于这方面的文档,所以请恕我直言。不幸的是,你的建议不适合我:这只是一个简单的例子来说明我的问题,但实际上“MyObj”比这复杂得多,我需要基于变量键选择器来比较属性。我考虑的解决方案是将操作分为两部分:一个简单的连接,然后是0元素与所有其他元素的交叉。两个操作的并集应该是我想要的结果。哦,如果您只需要使用一个变量键选择器,那么请保留您的
IEqualityComparer
类,并在where子句中使用它:
where new TestComparer().Equals(o1,o2)
。无论如何,有很多方法可以实现这一点,单交叉连接操作对我来说似乎更优雅。
"1var12var1"
"1var12var2"
"1var12var3"
"1var22var1"
"Equality test x:2018 y:2019 = False"
"Equality test x:2019 y:2020 = False"
"Equality test x:2018 y:2020 = False"
"Equality test x:2020 y:0 = True"
"Equality test x:2020 y:2018 = False"
"Equality test x:2019 y:2018 = False"
"Equality test x:2018 y:2018 = True"
var result = from o1 in operand1Data
             from o2 in operand2Data
             where o1.Year == 0 || o2.Year == 0 || o1.Year == o2.Year
             select o1.Var + o2.Var;
"1var12var1"
"1var12var2"
"1var12var3"
"1var22var1"