c# - 构建动态 Lambda 表达式时 order 和 select 有什么区别
问题描述
这个类使用字符串参数来排序记录。它的工作
public class Order
{
public static IEnumerable<T> OrderByDynamic<T>(IEnumerable<T> items, string sortby)
{
var property = typeof(T).GetProperty(sortby);
var result = typeof(Order)
.GetMethod("OrderByDynamic_Private", BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(typeof(T), property.PropertyType)
.Invoke(null, new object[] { items, sortby});
return (IEnumerable<T>)result;
}
private static IEnumerable<T> OrderByDynamic_Private<T, TKey>(IEnumerable<T> items, string sortby)
{
var parameter = Expression.Parameter(typeof(T), "x");
Expression<Func<T, TKey>> property_access_expression =
Expression.Lambda<Func<T, TKey>>(
Expression.Property(parameter, sortby),
parameter);
return items.OrderByDescending(property_access_expression.Compile());
throw new Exception("Invalid Sort Direction");
}
}
然后我想使用字符串参数来确定选择 lambda 表达式中的列。它只是将所有名称“订单”替换为“选择”并将返回值替换为 items.Select(property_access_expression.Compile());
然后我收到错误“错误 CS0266 无法将类型'System.Collections.Generic.IEnumerable' 隐式转换为'System.Collections.Generic.IEnumerable'。存在显式转换”如何解决此错误。
解决方案
据我了解,您想动态选择字段。我建议您使用不同的方法进行订购和选择。这是您如何为给定字段动态选择的方法。它只选择给定的字段并为其他字段打印默认值。所以它适用于您的用例。
class test
{
public string Code { get; set; }
public int Id { get; set; }
public override string ToString()
{
return Code + " " + Id;
}
}
class MainClass
{
public static void Main(string[] args)
{
List<test> list = new List<test>();
list.Add(new test { Code = "1", Id = 5 });
list.Add(new test { Code = "2", Id = 6 });
list.Add(new test { Code = "3", Id = 7 });
list.Add(new test { Code = "4", Id = 8 });
list.AsQueryable()
.Select(DynamicSelect<test>("Id"))
.ToList()
.ForEach(Console.WriteLine);
}
}
public static Expression<Func<T, T>> DynamicSelect<T>(string fields)
{
var members = fields.Split(',').Select(f => f.Trim());
var targetType = typeof(T);
var parameter = Expression.Parameter(targetType, "x");
var bindings = new List<MemberBinding>();
var target = Expression.Constant(null, targetType);
foreach (var name in members)
{
var targetMember = Expression.PropertyOrField(target, name);
var sourceMember = Expression.PropertyOrField(parameter, name);
bindings.Add(Expression.Bind(targetMember.Member, sourceMember));
}
var body = Expression.MemberInit(Expression.New(targetType), bindings);
return Expression.Lambda<Func<T, T>>(body, parameter);
}
推荐阅读
- javafx - 校对请求:没有红色下划线的代码,但如果我尝试显示 LineChart,则会收到错误消息。有人可以检查一下吗?
- amazon-web-services - 为 AWS Fargate 配置应用程序端口
- javascript - clone() 生成动态行但具有相同的 id 和 name
- android-databinding - Data Binding 多模块项目中没有这样的方法和字段错误
- javascript - laravel中codeigniter row_array的等价物是什么?
- python - 在与 python 的电报机器人对话期间触发消息,在超时之前
- javascript - 输入后按下提交按钮时的未定义值
- html - 无法选中一个复选框,在我仅选中表中的一个复选框后选中所有复选框
- javascript - Firebase Cloud Function中的Mailgun通过触发一次发送多次
- arrays - tkinter 在操作数组?