将 var 作为 T 参数传递

Passing var as T parameter

我正在尝试构建 OrderBy 表达式问题是当我将 var 对象传递给 TSource 时 TSource 的类型将是对象而不是实际列类型 例如实际类型是 int 但 TSource 类型是对象。

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);
    }

方法Activator.CreateInstance(Type type)returns对象,不是int。 也许您应该在使用前将其拆箱为 int;

遵循文档 Activator.CreateInstance return 对象,因此您必须将其转换为目标类型,或者您可以使用 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));

另外,你可以问一个问题“为什么扩展方法不能被动态调度?”

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.

因此,CLR 必须找到包含扩展方法的命名空间。 CLR 搜索它并找到方法命名空间,然后它只是将 result.OrderBy 更改为 Enumerable.OrderBy(result, ...)。但是,在 dynamic 关键字的情况下,DLR(动态语言运行时)必须在运行时找到此方法的 class,再次基于包含的命名空间。微软团队正确地认为成本太高而避免实施。