title: Linq and the Equality Operator: Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object'
body: <p>I'm trying to override the equality (==) operator in C# to handle comparing any type to a custom type (the custom type is really a wrapper/box around null).</p>
  
  <p>So I have this:</p>
  
  <pre><code>internal sealed class Nothing
  {
      public override bool Equals(object obj)
      {
          if (obj == null || obj is Nothing)
              return true;
          else
              return false;
      }
  
      public static bool operator ==(object x, Nothing y)
      {
          if ((x == null || x is Nothing) &amp;&amp; (y == null || y is Nothing))
              return true;
          return false;
      }
     ...
  }
  </code></pre>
  
  <p>Now if I make a call like:</p>
  
  <pre><code>Nothing n = new Nothing();
  bool equal = (10 == n);
  </code></pre>
  
  <p>It works perfectly fine. However, if I try to do this same thing through a Linq expression tree:</p>
  
  <pre><code>exp = Expression.Equal(
      Expression.Constant(10), 
      Expression.Constant(new Nothing(), typeof(Nothing))
  );
  </code></pre>
  
  <p>It throws the exception:</p>
  
  <pre><code>System.ArgumentException : Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean op_Equality(System.Object, PARTSFinder.Rules.Runtime.RulesNothing)'
      at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodInfo method, ReadOnlyCollection`1&amp; arguments)
      at System.Linq.Expressions.Expression.ValidateCallArgs(Expression instance, MethodInfo method, ReadOnlyCollection`1&amp; arguments)
      at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
      at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression[] arguments)
      at System.Linq.Expressions.ExpressionCompiler.GenerateBinaryMethod(ILGenerator gen, BinaryExpression b, StackType ask)
  </code></pre>
  
  <p>Any ideas on why the base system can convert Int32 to Object, but Linq can't, or how I can fix this?</p>
  
  <p>This whole thing stared because Linq also can't compare Int32 to Object in the first place:</p>
  
  <pre><code>exp = Expression.Equal(
      Expression.Constant(10), 
      Expression.Constant(null)
  );
  </code></pre>
  
  <p>Throws an exception stating that there is no comparison operator for "System.Int32" and "System.Object".</p>
  
  <hr>
  
  <p>Quick followup:</p>
  
  <p>The following do work without issue:</p>
  
  <pre><code>exp = Expression.Equal(
      Expression.Constant(10, typeof(object)), 
      Expression.Constant(new Nothing(), typeof(Nothing))
  );
  
  exp = Expression.Equal(
      Expression.Constant(10, typeof(object)), 
      Expression.Constant(null)
  );
  </code></pre>
  
  <p>So specifically casting everything to object.  So does Linq just not handle inheritance internally? Thats pretty annoying...</p>
  
  <hr>
  
  <p>Followup #2:</p>
  
  <p>I also tried using a custom comparison method:</p>
  
  <pre><code>exp = Expression.Equal(
      Expression.Constant(10),
      Expression.Constant(null),
      false,
      this.GetType().GetMethod("ValueEquals", BindingFlags.Public | BindingFlags.Static)
  );
  
      public static bool ValueEquals(object x, object y)
      {
          if (x == null &amp;&amp; y == null)
              return true;
          if (x.GetType() != y.GetType())
              return false;
          return x == y;
      }
  </code></pre>
  
  <p>This too throws an exception:</p>
  
  <pre><code>System.InvalidOperationException : The operands for operator 'Equal' do not match the parameters of method 'ValueEquals'.
      at System.Linq.Expressions.Expression.GetMethodBasedBinaryOperator(ExpressionType binaryType, Expression left, Expression right, MethodInfo method, Boolean liftToNull)
  </code></pre>
  
  <p>But again casting everything directly to object works:</p>
  
  <pre><code>exp = Expression.Equal(
      Expression.Constant(10, typeof(object)),
      Expression.Constant(null, typeof(object)),
      false,
      this.GetType().GetMethod("ValueEquals", BindingFlags.Public | BindingFlags.Static)
  );
  </code></pre>
  
  <p>So I guess I have my workaround... cast everything to object and use a custom comparison method. I'm still surprised Linq doesn't do the conversion automatically as normal C# does.</p>