C# 如何从实际类型推断TResult?
我使用的是实体框架、ASP.NET和C#3.5 我借用了以下代码,以便使用GridView中的sortExpression而不是实体的属性进行排序: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(' ');
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
可以避免您的方法中的一些工作。谢谢,这正是我想要的!