An expression of type "System.Int32" cannot be used for a parameter of type "System.Object" of the method "Boolean Equals (System.Object)"

I have one common grid column filter method that filters the grid view record with ColumnName and SearchText. here, when I work with nullable int datacolumn, an error occurs from this method:

Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean Equals(System.Object)' 

my method code:

  public static IQueryable<T> FilterForColumn<T>(this IQueryable<T> queryable, string colName, string searchText) { if (colName != null && searchText != null) { var parameter = Expression.Parameter(typeof(T), "m"); var propertyExpression = Expression.Property(parameter, colName); System.Linq.Expressions.ConstantExpression searchExpression = null; System.Reflection.MethodInfo containsMethod = null; // this must be of type Expression to accept different type of expressions // ie BinaryExpression, MethodCallExpression, ... System.Linq.Expressions.Expression body = null; Expression ex1 = null; Expression ex2 = null; switch (colName) { case "JobID": case "status_id": Int32 _int = Convert.ToInt32(searchText); searchExpression = Expression.Constant(_int); containsMethod = typeof(Int32).GetMethod("Equals", new[] { typeof(Int32) }); body = Expression.Call(propertyExpression, containsMethod, searchExpression); break; case "group_id": Int32? _int1 = Convert.ToInt32(searchText); searchExpression = Expression.Constant(_int1); containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) }); //Error throws from this line body = Expression.Call(propertyExpression, containsMethod, searchExpression); break; case "FileSize": case "TotalFileSize": Int64? _int2 = Convert.ToInt64(searchText); searchExpression = Expression.Constant(_int2); containsMethod = typeof(Int64?).GetMethod("Equals", new[] { typeof(Int64?) }); body = Expression.Call(propertyExpression, containsMethod, searchExpression); break; // section for DateTime? properties case "PublishDate": case "Birth_date": case "Anniversary_date": case "Profile_Updated_datetime": case "CompletedOn": DateTime currentDate = DateTime.ParseExact(searchText, "dd/MM/yyyy", null); DateTime nextDate = currentDate.AddDays(1); ex1 = Expression.GreaterThanOrEqual(propertyExpression, Expression.Constant(currentDate, typeof(DateTime?))); ex2 = Expression.LessThan(propertyExpression, Expression.Constant(nextDate, typeof(DateTime?))); body = Expression.AndAlso(ex1, ex2); break; // section for DateTime properties case "Created_datetime": case "Reminder_Date": case "News_date": case "thought_date": case "SubscriptionDateTime": case "Register_datetime": case "CreatedOn": DateTime currentDate1 = DateTime.ParseExact(searchText, "dd/MM/yyyy", null); DateTime nextDate1 = currentDate1.AddDays(1); ex1 = Expression.GreaterThanOrEqual(propertyExpression, Expression.Constant(currentDate1)); ex2 = Expression.LessThan(propertyExpression, Expression.Constant(nextDate1)); body = Expression.AndAlso(ex1, ex2); break; default: searchExpression = Expression.Constant(searchText); containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) }); body = Expression.Call(propertyExpression, containsMethod, searchExpression); break; } var predicate = Expression.Lambda<Func<T, bool>>(body, new[] { parameter }); return queryable.Where(predicate); } else { return queryable; } } 

here is my request that I fired:

 var query = Helper.GetUsers().Where(u => u.Id != user_id).OrderByDescending(u => u.Register_datetime).Select(u => new { Id = u.Id, Name = u.First_name + " " + u.Last_name, IsActive = u.IsActive, IsVerified = u.IsVerified, Username = u.Username, password = u.password, Birth_date = u.Birth_date, Anniversary_date = u.Anniversary_date, status_id = u.status_id, group_id = u.group_id, Profile_Updated_datetime = u.Profile_Updated_datetime, Register_datetime = u.Register_datetime }).FilterForColumn(ColumnName, SearchText).ToList(); 

here I include my query.GetType (). The result of ToString () for a better understanding of the types of columns in which I work on it.

 System.Collections.Generic.List`1[<>f__AnonymousType0`12[System.Int32,System.String,System.Boolean,System.Boolean,System.String,System.String,System.Nullable`1[System.DateTime],System.Nullable`1[System.DateTime],System.Int32,System.Nullable`1[System.Int32],System.Nullable`1[System.DateTime],System.DateTime]] 
+6
source share
2 answers

EDIT

Found a solution in this matter . You need to convert the expression to Object before calling the Equals(object) method:

 var converted = Expression.Convert(searchExpression, typeof(object)); body = Expression.Call(propertyExpression, containsMethod, converted); 

Nicodemus13 in the first place should work the proposal to explicitly set the type searchExpression to Object .

Original

I have not found the problem yet, but I reproduced the problem in SSCCE using Linqpad:

 void Main() { var myInstance = new myClass(); var equalsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) }); int? nullableInt = 1; var nullableIntExpr = System.Linq.Expressions.Expression.Constant(nullableInt); var myInstanceExpr = System.Linq.Expressions.Expression.Constant(myInstance); var propertyExpr = System.Linq.Expressions.Expression.Property(myInstanceExpr, "MyProperty"); var result = Expression.Call(propertyExpr,equalsMethod,nullableIntExpr); // This line throws the exception. Console.WriteLine(result); } class myClass{public int? MyProperty{get;set;}} 

This line:

 containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) }); 

returns a MethodInfo for the Int32?.Equals (Object other) method. Note that the parameter type is Object , not Int32 (or Int32? ), As you might expect.

The reason is typeof(Int32?) Is System.Nullable<Int32> , which only has the Equals(object) method.

+9
source

When playing with this in LinqPad, I think the problem is around:

searchExpression = Expression.Constant(_int1);

when you call:

containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });

The Equals method you are trying to call is object.Equals(object) , and the compiler tells you what type is int? is not the type of object that this method expects.

The simplest fix (although I'm not sure that the general code will work, although this particular error will disappear) is to change the Expression.Constant overload you call to the one that indicates the type that Equals expects:

searchExpression = Expression.Constant(_int1, typeof(object));

This compiles, however, there are a few comments.

  • Expression.Constant(_int1) your original Expression.Constant(_int1) leading to ConstantExpression with Type int not int? . You will need to specify a type with a null value if you need ( Expression.Constant(_int1, typeof(int?)) ). However, you still need to point it to object , as indicated above.

  • Job containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) }); should not work anyway, since there is no such int?.Equals(int?) method, the Equals method is an override of the method of the System.Object class, which takes an object parameter and is the root of the problem. You can also use: typeof(object).GetMethod("Equals", new[] { typeof(object) }); as the correct announcement.

As I said, it should compile with object , whether the code does what you expect, I'm not sure, but I think so. I look forward to whether this will work :)

+2
source

All Articles