C# 将var作为T参数传递

C# 将var作为T参数传递,c#,linq,dynamic,lambda,C#,Linq,Dynamic,Lambda,我正在尝试构建OrderBy表达式问题是,当我将var对象传递给TSource时,TSource的类型将是object,而不是实际的列类型 例如,实际类型为int,但TSource类型为object Type tblType = tblObj.GetType(); PropertyInfo propinfo; propinfo = tblType.GetProperty(ColumnName); if (propinfo == null) { return null; } var ins

我正在尝试构建OrderBy表达式问题是,当我将var对象传递给TSource时,TSource的类型将是object,而不是实际的列类型 例如,实际类型为int,但TSource类型为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));
这是lambda表达式生成器

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);
    }
公共表达式GetOrder(字符串字段、T项、TSource源)
{
if(string.IsNullOrEmpty(字段))
{
返回null;
}
var param=表达式参数(类型(T),“c”);
表达式转换=Expression.Convert(Expression.Property
(参数,字段),类型(TSource));
返回表达式.Lambda(转换,参数);
}

方法
Activator.CreateInstance(类型)
返回对象,而不是int。
可能你应该在使用前将其解装箱到int

遵循文档
Activator.CreateInstance
返回对象,因此您必须将其强制转换为目标类型,或者您可以使用
dynamic
类型,但编译器无法检查类型。

当不确定类型时,您可以使用
dynamic
以便在运行时级别找到该类型

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

您必须使用
dynamic
关键字或使用反射。 但是,使用
dynamic
可以更轻松地解决问题。 唯一的问题是,扩展方法不会被动态调度。 所以,您必须将扩展方法作为简单静态方法调用:

result = Enumerable.OrderBy(
           result, 
           GetOrder(item.ColumnName, tblObj, instance as dynamic));
此外,您还可以问一个问题“为什么扩展方法不能动态调度?”

委员会:

这意味着为了获得动态扩展方法调用 正确解决后,DLR必须在运行时知道 名称空间嵌套和“using”指令位于源代码中 代码。我们没有一种机制可以方便地对所有这些进行编码 将信息输入呼叫站点。我们曾考虑发明这样一种装置 机制,但决定这是太高的成本和生产太多 将风险安排在值得的范围内


因此,CLR必须找到保存扩展方法的名称空间。CLR对此进行搜索并找到方法名称空间,然后它只是将例如,
result.OrderBy
更改为
Enumerable.OrderBy(result,…)
。但是,对于
dynamic
关键字,
DLR
(动态语言运行时)必须在运行时再次基于包含的名称空间找到此方法的类。Microsoft团队正确地认为它的成本太高,并避免实施。

请注意,没有
var
对象或
var
类型
var
只是意味着编译器推断类型,因此在声明变量时不必显式地写下它
Activator.CreateInstance
返回
object
,因此您的行相当于
object instance=Activator.CreateInstance(propinfo.PropertyType)。最后,合法使用
动态
,感觉不像黑客!