C# 如何从实际类型推断TResult?

C# 如何从实际类型推断TResult?,c#,generics,linq-to-entities,type-inference,C#,Generics,Linq To Entities,Type Inference,我使用的是实体框架、ASP.NET和C#3.5 我借用了以下代码,以便使用GridView中的sortExpression而不是实体的属性进行排序: public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression) { string[] sortParts = sortExpression.Split(' ');

我使用的是实体框架、ASP.NET和C#3.5 我借用了以下代码,以便使用GridView中的sortExpression而不是实体的属性进行排序:

    public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression)
    {
        string[] sortParts = sortExpression.Split(' ');
        var param = Expression.Parameter(typeof(T), string.Empty);

        var property = Expression.Property(param, sortParts[0]);

        var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param);           

        if (sortParts.Length > 1 && sortParts[1].Equals("desc", StringComparison.OrdinalIgnoreCase))
        {
            return source.AsQueryable<T>().OrderByDescending(sortLambda);
        }

        return source.AsQueryable<T>().OrderBy(sortLambda);
    }
公共静态IEnumerable排序(此IEnumerable源代码,字符串排序表达式)
{
字符串[]sortpart=sortExpression.Split(“”);
var param=Expression.Parameter(typeof(T),string.Empty);
var property=Expression.property(param,sortpart[0]);
var sortLambda=Expression.Lambda(Expression.Convert(property,typeof(object)),param);
if(sortpart.Length>1&&sortpart[1].Equals(“desc”,StringComparison.OrdinalIgnoreCase))
{
返回source.AsQueryable().OrderByDescending(sortLambda);
}
返回source.AsQueryable().OrderBy(sortLambda);
}
问题是LINQ to实体不支持强制转换到对象。我需要实际的返回类型而不是对象,而不是Func。我想出了办法:

    public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression)
    {
        string[] sortParts = sortExpression.Split(' ');
        var param = Expression.Parameter(typeof(T), string.Empty);

        var property = Expression.Property(param, sortParts[0]);

        // NEW CODE HERE
        Type propertyType = property.Type;
        Type lambdaType = typeof(Func<,>).MakeGenericType(typeof(T), propertyType);
        var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, propertyType), param);
        //var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param);

        if (sortParts.Length > 1 && sortParts[1].Equals("desc", StringComparison.OrdinalIgnoreCase))
        {
            return source.AsQueryable<T>().OrderByDescending(sortLambda);
        }

        return source.AsQueryable<T>().OrderBy(sortLambda);
    }
公共静态IEnumerable排序(此IEnumerable源代码,字符串排序表达式)
{
字符串[]sortpart=sortExpression.Split(“”);
var param=Expression.Parameter(typeof(T),string.Empty);
var property=Expression.property(param,sortpart[0]);
//这里有新代码
类型propertyType=property.Type;
Type lambdaType=typeof(Func).MakeGenericType(typeof(T),propertyType);
var sortLambda=Expression.Lambda(Expression.Convert(property,propertyType),param);
//var sortLambda=Expression.Lambda(Expression.Convert(property,typeof(object)),param);
if(sortpart.Length>1&&sortpart[1].Equals(“desc”,StringComparison.OrdinalIgnoreCase))
{
返回source.AsQueryable().OrderByDescending(sortLambda);
}
返回source.AsQueryable().OrderBy(sortLambda);
}
现在的问题是,如果我有一个Int32,它将不会强制转换为object,而object仍然是返回类型。我是这样处理的:

    public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression)
    {
        string[] sortParts = sortExpression.Split(' ');
        var param = Expression.Parameter(typeof(T), string.Empty);

        var property = Expression.Property(param, sortParts[0]);

        // New code here
        Type propertyType = property.Type;
        Type lambdaType = typeof(Func<,>).MakeGenericType(typeof(T), propertyType);

        // NEWEST CODE HERE
        var sortLambda = Expression.Lambda(lambdaType, Expression.Convert(property, propertyType), param);
        //var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, propertyType), param);
        //var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param);


        if (sortParts.Length > 1 && sortParts[1].Equals("desc", StringComparison.OrdinalIgnoreCase))
        {
            return source.AsQueryable<T>().OrderByDescending(sortLambda);
        }

        return source.AsQueryable<T>().OrderBy(sortLambda);
    }
公共静态IEnumerable排序(此IEnumerable源代码,字符串排序表达式)
{
字符串[]sortpart=sortExpression.Split(“”);
var param=Expression.Parameter(typeof(T),string.Empty);
var property=Expression.property(param,sortpart[0]);
//这里有新代码
类型propertyType=property.Type;
Type lambdaType=typeof(Func).MakeGenericType(typeof(T),propertyType);
//这里有最新的代码
var sortLambda=Expression.Lambda(lambdaType,Expression.Convert(property,propertyType),param);
//var sortLambda=Expression.Lambda(Expression.Convert(property,propertyType),param);
//var sortLambda=Expression.Lambda(Expression.Convert(property,typeof(object)),param);
if(sortpart.Length>1&&sortpart[1].Equals(“desc”,StringComparison.OrdinalIgnoreCase))
{
返回source.AsQueryable().OrderByDescending(sortLambda);
}
返回source.AsQueryable().OrderBy(sortLambda);
}
但是,它不再编译。错误是:

无法从用法推断方法“System.Linq.Enumerable.OrderByDescending(System.Collections.Generic.IEnumerable,System.Func)”的类型参数。尝试显式指定类型参数

问题是我不想显式地指定类型参数


是否有人知道如何解决此问题,或者如何从“propertyType”推断TResult类型?

使用的方法,以及,应该满足您的需要。必要时,它使用反射来做中间的胆量,但是它起作用。还要注意
Expression.GetFuncType
Expression.GetActionType
可以避免您的方法中的一些工作。

谢谢,这正是我想要的!