我正在尝试构建OrderBy表达式问题是当我将var对象传递给TSource时,Type for TSource将是对象而不是Actual Column类型 例如,Actual类型是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);
}
答案 0 :(得分:4)
如果不确定类型,可以使用dynamic
,以便在运行时级别找到类型。
result = Enumerable.OrderBy(
result,
GetOrder(item.ColumnName, tblObj, (dynamic)instance));
答案 1 :(得分:2)
您必须使用dynamic
关键字或使用反射。
但是,您可以更轻松地使用dynamic
解决您的问题。
唯一的问题是,扩展方法不会被动态调度。
因此,您必须将扩展方法称为简单的静态方法:
result = Enumerable.OrderBy(
result,
GetOrder(item.ColumnName, tblObj, instance as dynamic));
此外,您可以提出问题&#34; 为什么无法动态调度扩展方法?&#34;
这意味着为了获得动态扩展方法的调用 正确解决,不知何故,DLR必须在运行时知道所有内容 命名空间嵌套和&#34;使用&#34;指令在你的来源 码。我们没有一个方便编码所有这些的机制 信息进入呼叫站点。我们考虑发明这样的 机制,但决定它成本太高,产生太多 安排风险是值得的。
因此,CLR必须找到包含扩展方法的命名空间。 CLR搜索它并找到方法命名空间,然后它只是更改为result.OrderBy
到Enumerable.OrderBy(result, ...)
。但是,如果是dynamic
关键字,DLR
(动态语言运行时)必须在运行时找到此方法的类,同样基于包含的命名空间。微软团队正确认为成本太高,无法实施。
答案 2 :(得分:0)
方法Activator.CreateInstance(Type type)
返回object,而不是int。
也许你应该在使用之前将它拆箱到int;
答案 3 :(得分:0)
遵循文档Activator.CreateInstance
返回对象,因此您必须将其强制转换为目标类型,或者您可以使用dynamic
类型,但编译器无法检查类型。