locked
Nullable types in Expression build RRS feed

  • Question

  • the Expression.Equal(Expression left, Expression right) method may throw InvalidOperationException when one of the 2 arguments is a Nullable type

    this is a simple console program I created to demostrate this problem:

     

    first a simple class that wrappers a Nullable<int>

    Code Snippet

        class MyClass
        {
            private int? myInt;

            public int? MyInt
            {
                get { return myInt; }
                set { myInt = value; }
            }
        }

     

    then the main program:

    Code Snippet
        class Program
        {
            static void Main(string[] args)
            {
                MyClass i = new MyClass();
                i.MyInt = 3;
                ParameterExpression param = Expression.Parameter(typeof(MyClass), "c");
                Expression left = Expression.Property(param, "MyInt");
                Expression right = Expression.Constant(i.MyInt);
                Expression filter = null;
                try
                {
                    filter = Expression.Equal(left, right);
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Console.ReadKey();
            }
        }

     

     

    after run this program, the catch block catches InvalidOperationException, the exception message is:

    The binary operator Equal is not defined for the types 'System.Nullable`1[System.Int32]' and 'System.Int32'.

     

    it is because that i.MyInt returns a int value (3), but the Expression.Property, when execute, returns a Nullable value, and no binary operator is defined between the 2 types

     

    any way to solve the problem? or just avoid to use the Nullable type in any entity classes?

     

    thx.

    Wednesday, September 12, 2007 2:45 AM

Answers

  • Both operands of the Equals node have to be the same type if they are value types.  So you'll have to convert the non-nullable type into a nullable type in order to do the comparison.

    Wednesday, September 12, 2007 4:03 AM

All replies

  • Both operands of the Equals node have to be the same type if they are value types.  So you'll have to convert the non-nullable type into a nullable type in order to do the comparison.

    Wednesday, September 12, 2007 4:03 AM
  • Thx!

     

    I have thought of converting the non-nullable type into nullable type in Expression build, but then I was confused on how to act the convertion.

     

    I was new on .NET framework, so any detail on how to convert a non-nullable value type into a nullable type would greatly help.

     

    Here are set of problems I encounted when doing the convertion:

    1.how to determine whether a variable(eg. Object value) if Nullable,

    Code Snippet
    if (value is Nullable)
    {
    //method stub
    }

    doesn't work, because Nullable is a static class that provides methods to nullable operation

     

    2.since Nullable<T> is a generic type, and it's hard to me to create an instance when "T" is missing

     

    thx~

    Wednesday, September 12, 2007 8:04 AM
  • ok finally I find the solution to this problem

     

    never try to convert a non-nullable valuetype into the correspoinding nullable type, so I tried to find a way to convert the nullable type into the non-nullable one

    luckily I find the Expression.Convert() method, so the final code is as below:

     

    Code Snippet

        class Program
        {
            static void Main(string[] args)
            {
                MyClass i = new MyClass();
                i.MyInt = 3;
                ParameterExpression param = Expression.Parameter(typeof(MyClass), "c");
                Expression left = Expression.Property(param, "MyInt");
                left = Expression.Convert(left, i.MyInt.GetType());
                Expression right = Expression.Constant(i.MyInt);
                Expression filter = null;
                try
                {
                    filter = Expression.Equal(left, right);
                    Console.WriteLine(filter);
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Console.ReadKey();
            }
        }

     

     

    and it works all fine for me, at least up to now

    • Proposed as answer by Peyman E Saturday, February 2, 2013 6:03 AM
    Wednesday, September 12, 2007 2:51 PM
  •  

    Expression.Convert is goog thing for converting to Nullable type. But what is about Guid type? As I can see Expression.Convert doesn't support Guid type ...

     

    How to build expression if we need to compare Guid and Nullable<Guid>?

     

    Thanks!

    Wednesday, November 7, 2007 3:21 PM
  • Method System.Linq.Expressions.Expression.Constant has an overload to accept a type.
    So the necessary code is Expression.Constant(someGuid, typeof(Guid?))
    Wednesday, April 8, 2009 12:08 PM