80

The following doesn't compile:

public void MyMethod<T>(T value)
{
    if (value == default(T))
    {
        // do stuff
    }
}

Error: Operator '==' cannot be applied to operands of type 'T' and 'T'

I can't use value == null because T may be a struct.
I can't use value.Equals(default(T)) because value may be null.
What is the proper way to test for equality to the default value?

Roman Boiko
  • 3,576
  • 1
  • 25
  • 41
Greg
  • 23,155
  • 11
  • 57
  • 79
  • 3
    replied to comment; and for info, `EqualityComparer` is the standard implementation used by the BCL, for example in `Dictionary<,>`. – Marc Gravell Dec 13 '09 at 23:28
  • 3
    possible duplicate of http://stackoverflow.com/questions/65351/null-or-default-comparsion-of-generic-argument-in-c-sharp – nawfal Apr 15 '13 at 10:28

2 Answers2

115

To avoid boxing for struct / Nullable<T>, I would use:

if (EqualityComparer<T>.Default.Equals(value,default(T)))
{
    // do stuff
}

This supports any T that implement IEquatable<T>, using object.Equals as a backup, and handles null etc (and lifted operators for Nullable<T>) automatically.

There is also Comparer<T>.Default which handles comparison tests. This handles T that implement IComparable<T>, falling back to IComparable - again handling null and lifted operators.

John K
  • 28,441
  • 31
  • 139
  • 229
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    Are you saying that `EqualityComparer.Default.Equals` has better performance than `Object.Equals`, or that it would give a correct value in some case that `Object.Equals` wouldn't? – Greg Dec 13 '09 at 22:57
  • 13
    Better performance (less boxing); consider `T=int`; to call `object.Equals` it has to box `value` and `default(T)` - that's two extra heap allocations + GC. Using `EqualityComparer` it has 3 different underlying implementations - `class`, `Nullable` and `struct` - it can then do everything (including `null` tests) without **any** boxing. The work of figuring out which implementation to use is only done once per type and cached, so still very fast. – Marc Gravell Dec 13 '09 at 23:27
  • @MarcGravell I can't seem to get this to work. I created a function with this inside to try and determine if the structure is still the default value. It seems to always return `FALSE` (not default value). Did I do something wrong? Ref: http://stackoverflow.com/questions/35897019/checking-a-structures-default-value – Arvo Bowen Mar 09 '16 at 16:30
39

What about

object.Equals(value, default(T))
Graviton
  • 81,782
  • 146
  • 424
  • 602
  • I knew it should be simple. Thank you. – Greg Dec 13 '09 at 06:46
  • 2
    +1. Tested. Works correctly with various types: `MyMethod(0); MyMethod(null); MyMethod(null);` - in each case returns true. – Roman Boiko Dec 13 '09 at 09:25
  • 2
    The downside with this is that it will unnecessarily box value types (which is why `EqualityComparer.Default.Equals` is preferred) – canton7 Jul 21 '20 at 13:12