0

我有一堂课是这样的:

 public class Foo : IEquatable<Bar>, IComparable{

 [DataMember]
 public Bar bar;

 public override bool Equals(object obj){
     //Check if not hte right object, return false;
     return this.bar == obj as Bar;
 }
 public bool Equals(Bar other){
    if(this.bar == other){
        return this.bar == other;
    }
 }
}

我希望能够有一个包含 bar 的 Foo 列表,并使用 Contains() 方法检查 Bar bar 是否在 Foo 列表中。到目前为止,我没有运气,从我读过的内容来看,如果它们具有定义 IEquatable 的相同父级或者它们是相同类型,则只能将类型与 IEquatable 进行比较。

任何人都知道您是否可以实施

List<Foo> foos.Contains(Bar bar) ?

另外,我想要一个 Bars 列表,并且能够删除 Foos 列表中包含的任何内容,例如;

 List<Bar> bars = bars.Where( r => (List<Foo>) !foos.Contains(r)).ToList();  \

这是我需要的最重要的东西,而且看起来很干净。当然,我可以在 for each 循环中进行这些比较,但如果可能的话,我想避免这种情况,并且可能不支付 n*m 的罚款。

谢谢

4

2 回答 2

2

在我看来,这段代码看起来很奇怪:

foos.Contains(bar)

你有什么想法:

foos.Any(f => f.Bar == bar)

更新后的代码 - 我假设您有集合bars并且您希望排除foos集合中 Foos 引用的所有 Bars:

bars.Except(foos.Select(f => f.Bar))
于 2013-08-01T19:55:15.450 回答
1

Empi 的回答foo.Any(f => f.Bar == bar)对我来说看起来很干净,但如果你想坚持比较 - 使用Enumerable.Contains的另一个覆盖并创建自定义“CompareFooByBar”比较器(你仍然需要Foo作为搜索词传递,但你可以使用完全假的一)。

class CompareFooByBar : IEqualityComparer<Foo>
{
    public bool Equals(Foo x, Foo y)
    {
        return x.Bar == y.Bar;
    }

    public int GetHashCode(Foo x)
    {
        return  x.Bar.GetHashCode();
    }
}

用法:

foos.Contains(new Foo{Bar = bar}, new CompareFooByBar())

另一种选择是完全作弊并使用简单地与固定值进行比较的比较器(但它会依赖于内部实现以特定的参数顺序Contains调用Equals并使Equals非对称):

class CompareFooToBar : IEqualityComparer<Foo>
{
    Bar bar;
    public CompareFooToBar(Bar bar) { this.bar = bar;}

    public bool Equals(Foo x, Foo y)
    {
        // hack - ignore y completely, assuming Contains pass element as x
        return x.Bar == bar; 
    }

    public int GetHashCode(Foo x) 
    {
        return  0;
    }
}

foos.Contains(null, new CompareFooToBar(bar))
于 2013-08-01T20:07:20.287 回答