鉴于这两个对象:
public class Foo{
public string Result {get;set;}
public List<Bar> Bars {get;set;}
}
public class Bar{
public string Left {get;set;}
public string Right {get;set;}
}
这些实例看起来像这样:
List<Foo> myFoos = new List<Foo>()
{
new Foo { Bars = new List<Bar>
{
new Bar { Left = "myLeft1", Right = "myValue1"},
new Bar { Left = "myLeft2", Right = "myValue2"}
},
Result = "TheWinningResult"},
new Foo { Bars = new List<Bar>
{
new Bar { Left = "myLeft2", Right = "myValue2"},
new Bar { Left = "myLeft3", Right = "myValue3"}
},
Result = "TheLosingResult"},
new Foo{ Bars = new List<Bar>
{
new Bar { Left = "myLeft1", Right = "myValue1"},
new Bar { Left = "myLeft2", Right = "myValue2"},
new Bar { Left = "myLeft3", Right = "myValue3"}
},
Result = "TheOtherLosingResult"},
};
List<Bar> bars = new List<Bar>()
{
new Bar{ Left = "myLeft1", Right = "myValue1" },
new Bar{ Left = "myLeft2", Right = "myValue2" }
};
我正在尝试查找FirstOrDefault()
Foo
,其中Foo.Bars
具有完全匹配的bars
在这种情况下,我正在尝试返回Foo
谁Result
是&#34; TheWinningResult&#34;
我尝试了以下内容:
Foo foo = myFoos.Where(t => t.Bars.All(t2 => bars.Contains(t2))).FirstOrDefault();
Foo foo = myFoos.Where(t => bars.All(r => t.Bars.Contains(r))).FirstOrDefault();
Foo foo = myFoos.FirstOrDefault(t => t.Bars.Any(r => bars.All(ru => ru.Left == r.Left && ru.Right == r.Right)));
知道我哪里错了吗?
更新
我忘了提及,Bars
中Foo
的顺序无关紧要。
答案 0 :(得分:4)
问题在于如何比较对象。默认情况下,比较由引用相等性完成。在这里,您需要一种不同的行为 - 按内容比较相等。为此,请覆盖Equals
的{{1}}和GetHashCode
:
Bar
然后检索正确的对象可以通过以下方式完成:
public override bool Equals(object obj)
{
var other = obj as Bar;
if (obj == null)
return false;
return other.Left == Left && other.Right == Right;
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Left.GetHashCode();
hash = hash * 23 + Right.GetHashCode();
return hash;
}
}
或者如果使用var result = myFoos.Where(item => bars.Count == item.Bars.Count &&
!bars.Except(item.Bars).Any());
:
SequenceEqual
另一种方法是实施var result = myFoos.Where(item => bars.SequenceEqual(item.Bars));
并调用匹配的IEqualityComparer<Bar>
重载:
Contains
至于你的第三次尝试,问题是var result = myFoos.Where(t => t.Bars.All(t2 => bars.Contains(t2, new BarEqualityComparer())));
和All
是相反的:你希望foo中的所有条形都匹配{{1}中的任何项目list:
Any
对于 bars
覆盖的内容,您可以阅读以下两项内容: