C#反射表达Linq
发布时间:2020-12-16 01:28:02 所属栏目:百科 来源:网络整理
导读:我在使用C#动态生成的lambda表达式时遇到了一些问题. 考虑以下情况: public class Person { public long Id { get; set; } public string Name { get; set; }}ListPerson persons = new ListPerson () { new Person { Id = 1,Name = "Foo" },new Person { I
我在使用C#动态生成的lambda表达式时遇到了一些问题.
考虑以下情况: public class Person { public long Id { get; set; } public string Name { get; set; } } List<Person> persons = new List<Person> () { new Person { Id = 1,Name = "Foo" },new Person { Id = 2,Name = "Bar" },new Person { Id = 3,Name = "Baz" },new Person { Id = 4,Name = null },}; 现在,做以下代码 ParameterExpression param = Expression.Parameter(typeof(Person),"arg"); Expression prop = Expression.Property(param,"Name"); Expression value = Expression.Constant("bar"); Type type = prop.Type; MethodInfo toLower = typeof(String).GetMethod("ToLower",Type.EmptyTypes); Expression expLower = Expression.Call(prop,toLower); Expression clausule = Expression.Call(expLower,type.GetMethod("Contains",new[] { type }),value); Expression notNull = Expression.NotEqual(prop,Expression.Constant(null)); clausule = Expression.And(notNull,clausule); var exp = Expression.Lambda<Func<T,bool>>(clausule,param); 上面的代码生成以下exp. //arg => ((arg.Name != null) And (arg.Name.ToLower().Contains("bar"))) 现在,尝试将其应用到我的列表中. 下面的过滤器有效 var filteredListThatWorks = persons.Where(arg => arg.Name != null && arg.Name.ToLower().Contains("bar")).ToList(); 下面的一个抛出Null对象的异常(因为Id 4名称) var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList(); 当由lambda生成时,相同的表达式会在手动输入时抛出exp. BR, 解决方法
并且是& ;;你想使用AndAlso(&&):
clausule = Expression.AndAlso(notNull,clausule); 如果有疑问,sharplab.io是一个很好的工具;如果我使用: Expression<Func<Person,bool>> filter = arg => arg.Name != null && arg.Name.ToLower().Contains("bar"); 它告诉我它编译成相当于: // ... BinaryExpression body = Expression.AndAlso(left,Expression.Call(instance,method,obj)); // ... (请注意,它必须对某些指令撒谎,因为它编译为无法在原始C#中实际表达的内容) see it in action (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |