Passing var as parameter T

I am trying to create an OrderBy expression, the problem is that when I pass a var object to a TSource object, the type for the TSource will not be of type Actual Column for example, the type Actual is int, but the type of TSource is an 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's 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);
    }

      

+3


source to share


4 answers


You either have to use a keyword dynamic

or use reflection. But you can more easily solve your issue with dynamic

. The only problem is that extension methods won't be dispatched dynamically. Thus, you must call the extension method as a simple static method:

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

      

Also, you might ask the question " Why can't extension methods be dispatched dynamically?"



asnwer by @EricLippert :

This means that in order to get the dynamic extension invocation properly resolved, somehow the DLR needs to know at runtime that all nested namespaces and "used" directives were in your source code. We have no mechanism to encode all this information into the call site. We thought it was a mechanism, but decided that it was too high a cost and too much risk of the schedule would be worth it.

So the CLR has to find the namespace that contains the extension method. CLR is looking for it, and he finds space method names, and then simply change, for example, result.OrderBy

on Enumerable.OrderBy(result, ...)

. But in the case of the keyword dynamic

DLR

(Dynamic Language Runtime) has to find the class of that method at runtime, again based on the included namespaces. The Microsoft team rightly believes that it is too high and does not allow for its implementation.

+2


source


If you are not sure about the type, you can use dynamic

to have the type found at the runlevel.



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

      

+4


source


The method Activator.CreateInstance(Type type)

returns an object, not an int. Maybe you should unbox it to an int before using it;

0


source


Follow the doc Activator.CreateInstance

return object, so you have to cast it to the assignment type dynamic

, or use the type , but the compiler cannot check the types.

0


source







All Articles