Take the 2-minute tour ×

So, the following lambda expression is not returning any elements in the collection, even though while stepping through I was able to verify that 1 item matches the criteria. I've added a sample of the class with it's IEquatable implementation.

...within a method, foo is a method parameter
var singleFoo = _barCollection.SingleOrDefault(b => b.Foo == foo);

The above returns nothing. Any suggestions as to what to do to make the expression above work?

public class Foo: IEquatable<Foo> 
    public string KeyProperty {get;set;}
    public bool Equals(Foo other)
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return other.KeyProperty==KeyProperty;
    public override bool Equals(object obj)
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof (Foo)) return false;
        return Equals((Foo) obj);
    public override int GetHashCode()
        return (KeyProperty != null ? KeyProperty.GetHashCode() : 0);

To make sure I didn't go insane, I created the following nUnit test which passes:

    public void verify_foo_comparison_works()
        var keyString = "keyValue";
        var bar = new Bar();
        bar.Foo = new Foo { KeyProperty = keyString };
        var basicFoo = new Foo { KeyProperty = keyString };
        var fromCollectionFoo = Bars.SingleFooWithKeyValue;
        Assert.AreEqual(bar.Foo, fromCollectionFoo);
        Assert.AreEqual(basicFoo, fromCollectionFoo);

Attempt at overriding == and !=:

    public static bool operator ==(Foo x, Foo y)
        if (ReferenceEquals(x, y))
            return true;
            return false;
        return x.KeyProperty == y.KeyProperty;
    public static bool operator !=(Foo x, Foo y)
        return !(x == y);
share|improve this question
Are you setting KeyProperty properly on all instances? You do this explicitly in your nUnit tests... –  Reed Copsey Feb 25 '10 at 21:42
Yes. While stepping through I have verified that the KeyProperty value is set. –  Carlos Bittencourt Feb 26 '10 at 15:20

4 Answers 4

They use EqualityComparer<T>.Default for equality comparisons and Comparer<T>.Default for ordered comparisons.

MSDN - EqualityComparer<T>.Default Remarks:

The Default property checks whether type T implements the System.IEquatable(Of T) generic interface and if so returns an EqualityComparer(Of T) that uses that implementation. Otherwise it returns an EqualityComparer(Of T) that uses the overrides of Object.Equals and Object.GetHashCode provided by T.

MSDN - Comparer<T>.Default Remarks:

The Comparer(Of T) returned by this property uses the System.IComparable(Of T) generic interface (IComparable<T> in C#, IComparable(Of T) in Visual Basic) to compare two objects. If type T does not implement the System.IComparable(Of T) generic interface, this property returns a Comparer(Of T) that uses the System.IComparable interface.

share|improve this answer

You are not redefining the == operator.

Change to:

var singleFoo = _barCollection.SingleOrDefault(b => b.Foo.Equals(foo));
share|improve this answer
Thanks for your suggestion. However, I'd rather not refactor all the places where the "bar.Foo == foo" has been implemented. –  Carlos Bittencourt Feb 25 '10 at 22:01
No problem. Define == on Foo and you can keep the predicates as is. –  Timores Feb 25 '10 at 22:25
Overwrote == and != as below and still no such luck. I gave up and refactored to use your initial suggestion. (I updated the original post to show the == and != implementations.) –  Carlos Bittencourt Feb 26 '10 at 16:05

You need to also override the == operator.

share|improve this answer
I'd rather switch to using theEquals method, like @Timores does. –  Svish Feb 25 '10 at 21:45

I've hit a similar problem with an IdentityKey class (that has implicit Guid conversions) - in this instance it's not really feasible to include an == operator override.

I say it's not feasible because with "mixed" comparisons I'll now have to cast the types to avoid ambiguity for the == operator overloads. ie. Instead of if(guidValue = identityKeyValue) it has to become if((IdentityKey)guidValue == identityKeyValue)

Whilst using .Equals is a solution, it doesn't feel natural to me?

share|improve this answer
If this is intended to be a question, please post it as a question and not as an answer. If it in some way depends on this question, link it in your own question and explain why it does not solve your problem. –  GalacticCowboy Jul 13 '10 at 16:46

Your Answer


