9

Following code is given, i want to just compare two objects inside a generic class.

public bool Compare<T>()
    {
        T var1 = default(T);
        T var2 = default(T);        
        return var1 == var2;
        //Error CS0019  Operator '==' cannot be applied to operands of type 'T' and 'T'
    }

Can anybody explain why it is not possible to compare these two objects in this generic class?

Teimo
  • 113
  • 7
  • Is the `default(T)` just as an example, or is that actually the case you want to compare? Else, I would say that it's just always `true`, as long as the implementer of a struct hasn't gone completely quirky with overriding `==`. – MicroVirus Apr 06 '16 at 11:48

3 Answers3

1

The Type T is not necessarily a reference type, T is a type argument and can be a class or a struct, so the compiler will not be able to make that assumption.

You can do like

public bool Compare<T>()
{           
        T var1 = default(T);
        T var2 = default(T);

        return !EqualityComparer<T>.Default.Equals(var1, var2);
}

You can also try to make T IComparable<T> or else you can try to use an IComparer<T> to your class.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • This will use `Object.Equals` (and `Object.GetHashCode`) for `T`, unless `T : IEquatable`, in which case it uses that. – MicroVirus Apr 06 '16 at 11:58
0

Quick option:

public bool Compare<T>()
{
    var t1 = default(T);
    var t2 = default(T);
    return object.Equals(t1, t2);
}

Generically correct option:

public bool Compare<T>()
{
    var t1 = default(T);
    var t2 = default(T);
    return EqualityComparer<T>.Default.Equals(t1, t2);
}

Be careful of the code below because if variable t1 is null you will receive an exception

public bool Compare<T>()
{
    var t1 = default(T);
    var t2 = default(T);
    return t1.Equals(t2);
}
-1

You can´t use the ==-operator on your Type T because there is no guarantee that this operator is defined on that type. Imagine T is of type KeyValuePair for example. You cannot write the following:

var areEqual = (new KeyValuePair<string, string>("1", "1") == new KeyValuePair<string, string>("2", "2"))

Make some constraint on your generic type such as where T : new() to allow only classes where the default-value is null.

EDIT: As a constraint on only classes is quite meaningless because reference-types allways default to null you can unbox your instance of T to object and then call the ==-operator:

public bool Compare<T>()
{
    object var1 = default(T);
    object var2 = default(T);
    if (var1 == null) return var1 == var2;
    return var1.Equals(var2);
}

This allows you to call the method for both value- and reference-types.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111