表达式树 C# - 空条件运算符 (?.)
Expression Tree C# - Null-Conditional oeprator (?.)
我正在尝试构建等效于“?”的表达式树。运算符。
var member = Expression.Property(Expression.Property("PropertyObjectName", value.Property),
"PropertyOfObject");
即:member.PropertyObjectName.PropertyOfObject
如果 PropertyObjectName
是我想避免的 null
,那当然会 抛出 Null exception
.
除了把 ConditionalExpression
放在那里之外,还有什么方法可以构建 member?.PropertyObjectName?.PropertyOfObject
吗?
你可以使用我的扩展方法
public static class ExpressionExtensions
{
public static Expression ElvisOperator(this Expression expression, string propertyOrField)
{
return Expression.Condition(Expression.NotEqual(expression, Expression.Constant(null)),
Expression.PropertyOrField(expression, propertyOrField),
Expression.Constant(null, expression.Type)
);
}
}
这会生成类似
的内容
IIF((x != null), x.propertyname, null)
那么你可以这样使用它:
public class TestClass
{
public int FirstProp { get; set; }
public TestClass SecondProp { get; set; }
}
var variable = Expression.Parameter(typeof(TestClass), "x");
var nullSafe = variable.ElvisOperator("SecondProp");
我做了这个测试:
List<TestClass> tests = new List<TestClass>(){
new TestClass() { FirstProp = 1, SecondProp = new TestClass() { SecondProp = new TestClass() } },
new TestClass() { FirstProp = 2 },
new TestClass() { FirstProp = 3, SecondProp = new TestClass() },
new TestClass() { FirstProp = 4 },
};
var variable = Expression.Parameter(typeof(TestClass), "x");
var nullSafe = variable.ElvisOperator("SecondProp").ElvisOperator("SecondProp");
var cond = Expression.NotEqual(nullSafe, Expression.Constant(null, variable.Type));
var lambda = Expression.Lambda<Func<TestClass, bool>>(cond, new ParameterExpression[] { variable });
tests = tests.AsQueryable().Where(lambda).ToList();
Console.WriteLine(tests.Count);
这会在控制台上打印 1,因为这样过滤列表:
.Where(x => x.SecondProp?SecondProp != null)
我正在尝试构建等效于“?”的表达式树。运算符。
var member = Expression.Property(Expression.Property("PropertyObjectName", value.Property),
"PropertyOfObject");
即:member.PropertyObjectName.PropertyOfObject
如果 PropertyObjectName
是我想避免的 null
,那当然会 抛出 Null exception
.
除了把 ConditionalExpression
放在那里之外,还有什么方法可以构建 member?.PropertyObjectName?.PropertyOfObject
吗?
你可以使用我的扩展方法
public static class ExpressionExtensions
{
public static Expression ElvisOperator(this Expression expression, string propertyOrField)
{
return Expression.Condition(Expression.NotEqual(expression, Expression.Constant(null)),
Expression.PropertyOrField(expression, propertyOrField),
Expression.Constant(null, expression.Type)
);
}
}
这会生成类似
的内容IIF((x != null), x.propertyname, null)
那么你可以这样使用它:
public class TestClass
{
public int FirstProp { get; set; }
public TestClass SecondProp { get; set; }
}
var variable = Expression.Parameter(typeof(TestClass), "x");
var nullSafe = variable.ElvisOperator("SecondProp");
我做了这个测试:
List<TestClass> tests = new List<TestClass>(){
new TestClass() { FirstProp = 1, SecondProp = new TestClass() { SecondProp = new TestClass() } },
new TestClass() { FirstProp = 2 },
new TestClass() { FirstProp = 3, SecondProp = new TestClass() },
new TestClass() { FirstProp = 4 },
};
var variable = Expression.Parameter(typeof(TestClass), "x");
var nullSafe = variable.ElvisOperator("SecondProp").ElvisOperator("SecondProp");
var cond = Expression.NotEqual(nullSafe, Expression.Constant(null, variable.Type));
var lambda = Expression.Lambda<Func<TestClass, bool>>(cond, new ParameterExpression[] { variable });
tests = tests.AsQueryable().Where(lambda).ToList();
Console.WriteLine(tests.Count);
这会在控制台上打印 1,因为这样过滤列表:
.Where(x => x.SecondProp?SecondProp != null)