score:2

Accepted answer

score:1

That depends on the object. If it's a value type, usually the vaules are compared, it it's a reference type, the references are compared, unless the Equals() method is overridden.

From MSDN:

The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object. Bitwise equality means the objects that are compared have the same binary representation.

Note that a derived type might override the Equals method to implement value equality.

score:0

The ‘equals’ within a join query uses the default equality comparer to compare keys using a keyed lookup. The join is implemented in Enumerable.Join and the key can be either a value or a reference. When querying using Linq to Sql the key is usually a value as primary keys normally map to value types. However as the following code illustrates the equals comparison can be either by value or by reference which ever is appropriate for the key type:

KeyObj k1 = new KeyObj(); k1.Id = 1001;
        KeyObj k2 = new KeyObj(); k2.Id = 1002;
        KeyObj k3 = new KeyObj(); k3.Id = 1003;
        KeyObj k4 = new KeyObj(); k4.Id = 1004;
        KeyObj k5 = new KeyObj(); k4.Id = 1005;

        List<Foo> foos = 
            new List<Foo>()
            {
                new Foo("o1",k1),
                new Foo("o2",k2),
                new Foo("o4",k5)
            };

        List<Bar> bars =
            new List<Bar>()
            {
                new Bar("o2",k1),
                new Bar("o3",k2),
                new Bar("o4",k4),
                new Bar("o5",k5)
            };


        var foobar = from f in foos
                     join b in bars on f.Ko equals b.Ko
                     select f.Name + " in foos joined by reference with " + b.Name + " in bars ";

        foreach (var v in foobar)
        {
            Debug.WriteLine(v);
        }

        foobar = from f in foos
                 join b in bars on f.Name equals b.Name
                 select f.Name + " in foos joined by value with " + b.Name + " in bars ";

        foreach (var v in foobar)
        {
            Debug.WriteLine(v);
        }

class KeyObj { public int Id { get; set; } }

class Foo : Base
{
    public Foo(string s, KeyObj ko) : base(s, ko) { }
}

class Bar : Base
{
    public Bar(string s, KeyObj ko) : base(s, ko) { }
}

class Base
{
    string _name = "";
    public string Name { get { return _name; }}

    KeyObj _ko = null;
    public KeyObj Ko { get { return _ko; }}

    public Base(string s, KeyObj ko)
    {
        _name = s;
        _ko = ko;
    }
}

The output from this is:

o1 in foos joined by reference with o2 in bars

o2 in foos joined by reference with o3 in bars

o4 in foos joined by reference with o5 in bars

o2 in foos joined by value with o2 in bars

o4 in foos joined by value with o4 in bars

score:0

From MSDN: http://msdn.microsoft.com/en-us/library/bb311040.aspx

The equals operator

A join clause performs an equijoin. In other words, you can only base matches on the equality of two keys. Other types of comparisons such as "greater than" or "not equals" are not supported. To make clear that all joins are equijoins, the join clause uses the equals keyword instead of the == operator. The equals keyword can only be used in a join clause and it differs from the == operator in one important way. With equals, the left key consumes the outer source sequence, and the right key consumes the inner source. The outer source is only in scope on the left side of equals and the inner source sequence is only in scope on the right side.


Related Articles