3

I am trying to build OrderBy expression the problem is when I pass var object to TSource the Type for TSource will be object not the Actual Column type for example the Actual type is int but TSource type is object.

Type tblType = tblObj.GetType();
PropertyInfo propinfo;
propinfo = tblType.GetProperty(ColumnName);
if (propinfo == null)
{
    return null;
}
var instance = Activator.CreateInstance(propinfo.PropertyType);
result = result.OrderBy(GetOrder(item.ColumnName, tblObj, instance));

and here is the lambda expression builder

public Expression<Func<T, TSource>> GetOrder<T,TSource>(string field, T item,TSource source)
    {
        if (string.IsNullOrEmpty(field))
        {
            return null;
        }
        var param = Expression.Parameter(typeof(T), "c");
        Expression conversion = Expression.Convert(Expression.Property
        (param, field), typeof(TSource));  
        return Expression.Lambda<Func<T, TSource>>(conversion, param);
    }
Bakri
  • 597
  • 10
  • 22
  • 2
    Note that there's no `var` object or `var` type. `var` simply means that the compiler infers the type, so you don't have to explicitly write it down when declaring a variable. `Activator.CreateInstance` returns `object`, so your line is equivalent to `object instance = Activator.CreateInstance(propinfo.PropertyType);`. – sloth Jun 26 '15 at 07:48

4 Answers4

4

When not sure of the type, you can use dynamic so the type will be found at runtime level.

result = Enumerable.OrderBy(
       result, 
       GetOrder(item.ColumnName, tblObj, (dynamic)instance));
Bellash
  • 7,560
  • 6
  • 53
  • 86
2

You either must use dynamic keyword or use reflection. But, you can solve your probelm with dynamic more easily. The only problem is that, extension methods will not be dynamically dispatched. So, you must call extension method as simple static method:

result = Enumerable.OrderBy(
           result, 
           GetOrder(item.ColumnName, tblObj, instance as dynamic));

Also, you can ask a question "Why extension methods can not be dynamically dispatched?"

The asnwer by @EricLippert:

That means that in order to get a dynamic extension method invocation resolved correctly, somehow the DLR has to know at runtime what all the namespace nestings and "using" directives were in your source code. We do not have a mechanism handy for encoding all that information into the call site. We considered inventing such a mechanism, but decided that it was too high cost and produced too much schedule risk to be worth it.

So, CLR must find the namespace which holds extension method. CLR searches this and it it finds the method namespace, then it just changes for example, result.OrderBy to Enumerable.OrderBy(result, ...). But, in case of dynamic keyword, DLR(Dynamic Language Runtime) must find the class of this method in runtime, again based on included namespaces. Microsoft team rightly thinks that it is too high cost and avoids to implement it.

Community
  • 1
  • 1
Farhad Jabiyev
  • 26,014
  • 8
  • 72
  • 98
0

Method Activator.CreateInstance(Type type) returns object, not int. May be you should unbox it to int before use;

Fabjan
  • 13,506
  • 4
  • 25
  • 52
0

Follow the documentation Activator.CreateInstance return object, so you have to cast it to destination type or you can use dynamic type, but than compiler can't check types.

rechandler
  • 756
  • 8
  • 22