<p>I have a generic method defined like this:</p>

<pre><code>public void MyMethod&lt;T&gt;(T myArgument)
</code></pre>

<p>The first thing I want to do is check if the value of myArgument is the default value for that type, something like this:</p>

<pre><code>if (myArgument == default(T))
</code></pre>

<p>But this doesn't compile because I haven't guaranteed that T will implement the == operator.  So I switched the code to this:</p>

<pre><code>if (myArgument.Equals(default(T)))
</code></pre>

<p>Now this compiles, but will fail if myArgument is null, which is part of what I'm testing for.  I can add an explicit null check like this:</p>

<pre><code>if (myArgument == null || myArgument.Equals(default(T)))
</code></pre>

<p>Now this feels redundant to me.  ReSharper is even suggesting that I change the myArgument == null part into myArgument == default(T) which is where I started.  Is there a better way to solve this problem?</p>

<p>I need to support <b>both</b> references types and value types.</p>

[{'answer_id': 65423, 'author': 'Eric Schoonover', 'author_id': 3957, 'author_profile': 'https://Stackoverflow.com/users/3957', 'pm_score': 5, 'selected': False, 'text': '<p>I was able to locate a <a href="http://msdn.microsoft.com/en-us/library/system.icomparable.compareto.aspx" rel="noreferrer">Microsoft Connect article</a> that discusses this issue in some detail:</p>\n<blockquote>\n<p>Unfortunately, this behavior is by design and there is not an easy solution to enable use of with type parameters that may contain value types.</p>\n<p>If the types are known to be reference types, the default overload of defined on object tests variables for reference equality, although a type may specify its own custom overload. The compiler determines which overload to use based on the static type of the variable (the determination is not polymorphic). Therefore, if you change your example to constrain the generic type parameter T to a non-sealed reference type (such as Exception), the compiler can determine the specific overload to use and the following code would compile:</p>\n</blockquote>\n<pre><code>public class Test&lt;T&gt; where T : Exception\n</code></pre>\n<blockquote>\n<p>If the types are known to be value types, performs specific value equality tests based on the exact types used. There is no good &quot;default&quot; comparison here since reference comparisons are not meaningful on value types and the compiler cannot know which specific value comparison to emit. The compiler could emit a call to ValueType.Equals(Object) but this method uses reflection and is quite inefficient compared to the specific value comparisons. Therefore, even if you were to specify a value-type constraint on T, there is nothing reasonable for the compiler to generate here:</p>\n</blockquote>\n<pre><code>public class Test&lt;T&gt; where T : struct\n</code></pre>\n<blockquote>\n<p>In the case you presented, where the compiler does not even know whether T is a value or reference type, there is similarly nothing to generate that would be valid for all possible types. A reference comparison would not be valid for value types and some sort of value comparison would be unexpected for reference types that do not overload.</p>\n</blockquote>\n<p>Here is what you can do...</p>\n<p>I have validated that both of these methods work for a generic comparison of reference and value types:</p>\n<pre><code>object.Equals(param, default(T))\n</code></pre>\n<p>or</p>\n<pre><code>EqualityComparer&lt;T&gt;.Default.Equals(param, default(T))\n</code></pre>\n<p>To do comparisons with the &quot;==&quot; operator you will need to use one of these methods:</p>\n<p>If all cases of T derive from a known base class you can let the compiler know using generic type restrictions.</p>\n<pre><code>public void MyMethod&lt;T&gt;(T myArgument) where T : MyBase\n</code></pre>\n<p>The compiler then recognizes how to perform operations on <code>MyBase</code> and will not throw the &quot;Operator \'==\' cannot be applied to operands of type \'T\' and \'T\'&quot; error that you are seeing now.</p>\n<p>Another option would be to restrict T to any type that implements <code>IComparable</code>.</p>\n<pre><code>public void MyMethod&lt;T&gt;(T myArgument) where T : IComparable\n</code></pre>\n<p>And then use the <code>CompareTo</code> method defined by the <a href="http://msdn.microsoft.com/en-us/library/system.icomparable.compareto.aspx" rel="noreferrer">IComparable interface</a>.</p>\n'}, {'answer_id': 65445, 'author': 'Kent Boogaart', 'author_id': 5380, 'author_profile': 'https://Stackoverflow.com/users/5380', 'pm_score': 7, 'selected': False, 'text': "<p>How about this:</p>\n\n<pre><code>if (object.Equals(myArgument, default(T)))\n{\n    //...\n}\n</code></pre>\n\n<p>Using the <code>static object.Equals()</code> method avoids the need for you to do the <code>null</code> check yourself. Explicitly qualifying the call with <code>object.</code> probably isn't necessary depending on your context, but I normally prefix <code>static</code> calls with the type name just to make the code more soluble.</p>\n"}, {'answer_id': 65457, 'author': 'caryden', 'author_id': 313, 'author_profile': 'https://Stackoverflow.com/users/313', 'pm_score': -1, 'selected': False, 'text': "<p>Don't know if this works with your requirements or not, but you could constrain T to be a Type that implements an interface such as IComparable and then use the ComparesTo() method from that interface (which IIRC supports/handles nulls) like this:</p>\n\n<pre><code>public void MyMethod&lt;T&gt;(T myArgument) where T : IComparable\n...\nif (0 == myArgument.ComparesTo(default(T)))\n</code></pre>\n\n<p>There are probably other interfaces that you could use as well IEquitable, etc.</p>\n"}, {'answer_id': 65461, 'author': 'Lasse V. Karlsen', 'author_id': 267, 'author_profile': 'https://Stackoverflow.com/users/267', 'pm_score': 4, 'selected': False, 'text': '<p>Try this:</p>\n\n<pre><code>if (EqualityComparer&lt;T&gt;.Default.Equals(myArgument, default(T)))\n</code></pre>\n\n<p>that should compile, and do what you want.</p>\n'}, {'answer_id': 65498, 'author': 'cfeduke', 'author_id': 5645, 'author_profile': 'https://Stackoverflow.com/users/5645', 'pm_score': -1, 'selected': False, 'text': "<p>@ilitirit:</p>\n\n<pre><code>public class Class&lt;T&gt; where T : IComparable\n{\n    public T Value { get; set; }\n    public void MyMethod(T val)\n    {\n        if (Value == val)\n            return;\n    }\n}\n</code></pre>\n\n<p>Operator '==' cannot be applied to operands of type 'T' and 'T'</p>\n\n<p>I can't think of a way to do this without the explicit null test followed by invoking the Equals method or object.Equals as suggested above.</p>\n\n<p>You can devise a solution using System.Comparison but really that's going to end up with way more lines of code and increase complexity substantially.</p>\n"}, {'answer_id': 677151, 'author': 'Damian Powell', 'author_id': 30321, 'author_profile': 'https://Stackoverflow.com/users/30321', 'pm_score': 1, 'selected': False, 'text': '<p>I think you probably need to split this logic into two parts and check for null first.</p>\n\n<pre><code>public static bool IsNullOrEmpty&lt;T&gt;(T value)\n{\n    if (IsNull(value))\n    {\n        return true;\n    }\n    if (value is string)\n    {\n        return string.IsNullOrEmpty(value as string);\n    }\n    return value.Equals(default(T));\n}\n\npublic static bool IsNull&lt;T&gt;(T value)\n{\n    if (value is ValueType)\n    {\n        return false;\n    }\n    return null == (object)value;\n}\n</code></pre>\n\n<p>In the IsNull method, we\'re relying on the fact that ValueType objects can\'t be null by definition so if value happens to be a class which derives from ValueType, we already know it\'s not null. On the other hand, if it\'s not a value type then we can just compare value cast to an object against null. We could avoid the check against ValueType by going straight to a cast to object, but that would mean that a value type would get boxed which is something we probably want to avoid since it implies that a new object is created on the heap.</p>\n\n<p>In the IsNullOrEmpty method, we\'re checking for the special case of a string. For all other types, we\'re comparing the value (which already know is <em>not</em> null) against it\'s default value which for all reference types is null and for value types is usually some form of zero (if they\'re integral).</p>\n\n<p>Using these methods, the following code behaves as you might expect:</p>\n\n<pre><code>class Program\n{\n    public class MyClass\n    {\n        public string MyString { get; set; }\n    }\n\n    static void Main()\n    {\n        int  i1 = 1;    Test("i1", i1); // False\n        int  i2 = 0;    Test("i2", i2); // True\n        int? i3 = 2;    Test("i3", i3); // False\n        int? i4 = null; Test("i4", i4); // True\n\n        Console.WriteLine();\n\n        string s1 = "hello";      Test("s1", s1); // False\n        string s2 = null;         Test("s2", s2); // True\n        string s3 = string.Empty; Test("s3", s3); // True\n        string s4 = "";           Test("s4", s4); // True\n\n        Console.WriteLine();\n\n        MyClass mc1 = new MyClass(); Test("mc1", mc1); // False\n        MyClass mc2 = null;          Test("mc2", mc2); // True\n    }\n\n    public static void Test&lt;T&gt;(string fieldName, T field)\n    {\n        Console.WriteLine(fieldName + ": " + IsNullOrEmpty(field));\n    }\n\n    // public static bool IsNullOrEmpty&lt;T&gt;(T value) ...\n\n    // public static bool IsNull&lt;T&gt;(T value) ...\n}\n</code></pre>\n'}, {'answer_id': 864292, 'author': 'Joel Coehoorn', 'author_id': 3043, 'author_profile': 'https://Stackoverflow.com/users/3043', 'pm_score': 3, 'selected': False, 'text': '<p>(Edited)</p>\n\n<p>Marc Gravell has the best answer, but I wanted to post a simple code snippet I worked up to demonstrate it.  Just run this in a simple C# console app:</p>\n\n<pre><code>public static class TypeHelper&lt;T&gt;\n{\n    public static bool IsDefault(T val)\n    {\n         return EqualityComparer&lt;T&gt;.Default.Equals(obj,default(T));\n    }\n}\n\nstatic void Main(string[] args)\n{\n    // value type\n    Console.WriteLine(TypeHelper&lt;int&gt;.IsDefault(1)); //False\n    Console.WriteLine(TypeHelper&lt;int&gt;.IsDefault(0)); // True\n\n    // reference type\n    Console.WriteLine(TypeHelper&lt;string&gt;.IsDefault("test")); //False\n    Console.WriteLine(TypeHelper&lt;string&gt;.IsDefault(null)); //True //True\n\n    Console.ReadKey();\n}\n</code></pre>\n\n<p>One more thing: can someone with VS2008 try this as an extension method?  I\'m stuck with 2005 here and I\'m curious to see if that would be allowed.</p>\n\n<hr>\n\n<p><strong>Edit:</strong> Here is how to get it working as an extension method:</p>\n\n<pre><code>using System;\nusing System.Collections.Generic;\n\nclass Program\n{\n    static void Main()\n    {\n        // value type\n        Console.WriteLine(1.IsDefault());\n        Console.WriteLine(0.IsDefault());\n\n        // reference type\n        Console.WriteLine("test".IsDefault());\n        // null must be cast to a type\n        Console.WriteLine(((String)null).IsDefault());\n    }\n}\n\n// The type cannot be generic\npublic static class TypeHelper\n{\n    // I made the method generic instead\n    public static bool IsDefault&lt;T&gt;(this T val)\n    {\n        return EqualityComparer&lt;T&gt;.Default.Equals(val, default(T));\n    }\n}\n</code></pre>\n'}, {'answer_id': 864306, 'author': 'Nick Farina', 'author_id': 66673, 'author_profile': 'https://Stackoverflow.com/users/66673', 'pm_score': 3, 'selected': False, 'text': "<p>To handle all types of T, including where T is a primitive type, you'll need to compile in both methods of comparison:</p>\n\n<pre><code>    T Get&lt;T&gt;(Func&lt;T&gt; createObject)\n    {\n        T obj = createObject();\n        if (obj == null || obj.Equals(default(T)))\n            return obj;\n\n        // .. do a bunch of stuff\n        return obj;\n    }\n</code></pre>\n"}, {'answer_id': 864309, 'author': 'Reed Copsey', 'author_id': 65358, 'author_profile': 'https://Stackoverflow.com/users/65358', 'pm_score': 2, 'selected': False, 'text': "<p>There is going to be a problem here -</p>\n\n<p>If you're going to allow this to work for any type, default(T) will always be null for reference types, and 0 (or struct full of 0) for value types.</p>\n\n<p>This is probably not the behavior you're after, though.  If you want this to work in a generic way, you probably need to use reflection to check the type of T, and handle value types different than reference types.</p>\n\n<p>Alternatively, you could put an interface constraint on this, and the interface could provide a way to check against the default of the class/struct.</p>\n"}, {'answer_id': 864860, 'author': 'Marc Gravell', 'author_id': 23354, 'author_profile': 'https://Stackoverflow.com/users/23354', 'pm_score': 10, 'selected': True, 'text': '<p>To avoid boxing, the best way to compare generics for equality is with <code>EqualityComparer&lt;T&gt;.Default</code>. This respects <code>IEquatable&lt;T&gt;</code> (without boxing) as well as <code>object.Equals</code>, and handles all the <code>Nullable&lt;T&gt;</code> "lifted" nuances. Hence:</p>\n\n<pre><code>if(EqualityComparer&lt;T&gt;.Default.Equals(obj, default(T))) {\n    return obj;\n}\n</code></pre>\n\n<p>This will match:</p>\n\n<ul>\n<li>null for classes</li>\n<li>null (empty) for <code>Nullable&lt;T&gt;</code></li>\n<li>zero/false/etc for other structs</li>\n</ul>\n'}, {'answer_id': 6857841, 'author': 'Scott McKay', 'author_id': 684911, 'author_profile': 'https://Stackoverflow.com/users/684911', 'pm_score': -1, 'selected': False, 'text': "<p>I think you were close.</p>\n\n<pre><code>if (myArgument.Equals(default(T)))\n</code></pre>\n\n<p>Now this compiles, but will fail if <code>myArgument</code> is null, which is part of what I'm testing  for. I can add an explicit null check like this:</p>\n\n<p>You just need to reverse the object on which the equals is being called for an elegant null-safe approach.</p>\n\n<pre><code>default(T).Equals(myArgument);\n</code></pre>\n"}, {'answer_id': 51236830, 'author': 'kofifus', 'author_id': 460084, 'author_profile': 'https://Stackoverflow.com/users/460084', 'pm_score': 0, 'selected': False, 'text': '<p>I use:</p>\n\n<pre><code>public class MyClass&lt;T&gt;\n{\n  private bool IsNull() \n  {\n    var nullable = Nullable.GetUnderlyingType(typeof(T)) != null;\n    return nullable ? EqualityComparer&lt;T&gt;.Default.Equals(Value, default(T)) : false;\n  }\n}\n</code></pre>\n'}, {'answer_id': 60281314, 'author': 'dynamiclynk', 'author_id': 1427166, 'author_profile': 'https://Stackoverflow.com/users/1427166', 'pm_score': 2, 'selected': False, 'text': '<p>Extension method based on accepted answer.</p>\n\n<pre><code>   public static bool IsDefault&lt;T&gt;(this T inObj)\n   {\n       return EqualityComparer&lt;T&gt;.Default.Equals(inObj, default);\n   }\n</code></pre>\n\n<p>Usage:</p>\n\n<pre><code>   private bool SomeMethod(){\n       var tValue = GetMyObject&lt;MyObjectType&gt;();\n       if (tValue == null || tValue.IsDefault()) return false;\n   }\n</code></pre>\n\n<p>Alternate with null to simplify:</p>\n\n<pre><code>   public static bool IsNullOrDefault&lt;T&gt;(this T inObj)\n   {\n       if (inObj == null) return true;\n       return EqualityComparer&lt;T&gt;.Default.Equals(inObj, default);\n   }\n</code></pre>\n\n<p>Usage:</p>\n\n<pre><code>   private bool SomeMethod(){\n       var tValue = GetMyObject&lt;MyObjectType&gt;();\n       if (tValue.IsNullOrDefault()) return false;\n   }\n</code></pre>\n'}, {'answer_id': 66327304, 'author': 'Kosmas', 'author_id': 2833737, 'author_profile': 'https://Stackoverflow.com/users/2833737', 'pm_score': 0, 'selected': False, 'text': "<p>Just a hacky answer and as a reminder for myself.\nBut I find this quite helpful for my project.\nThe reason I write it like this is that because I don't want default integer 0 being marked as null if the value is 0</p>\n<pre><code>private static int o;\npublic static void Main()\n{\n    //output: IsNull = False -&gt; IsDefault = True\n    Console.WriteLine( &quot;IsNull = &quot; + IsNull( o ) + &quot; -&gt; IsDefault = &quot; + IsDefault(o)); \n}\n\npublic static bool IsNull&lt;T&gt;(T paramValue)\n{\n  if( string.IsNullOrEmpty(paramValue + &quot;&quot; ))\n    return true;\n  return false;\n}\n\npublic static bool IsDefault&lt;T&gt;(T val)\n{\n  return EqualityComparer&lt;T&gt;.Default.Equals(val, default(T));\n}\n</code></pre>\n"}]
['https://Stackoverflow.com/questions/65351', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/8739/']