簡體   English   中英

C#反射表達Linq

[英]C# Reflection Expression Linq

我在使用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,

And& ; 你想使用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#中實際表達的內容)

看到它在行動

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM