如何通过Expression访问嵌套类属性?遇NullReferenceException及属性命名疑问
问题解答
嗨,我来帮你搞定这两个问题:
一、User类中Department类型属性的名称
这种属性在面向对象编程里一般叫做关联属性——它用来表示两个类之间的关联关系;如果是在ORM(比如Entity Framework)的场景下,这类属性通常被称为导航属性,用来体现实体之间的从属或关联关系。本质上它就是一个对象类型的成员属性,属于复合属性的一种,因为它的类型不是基础数据类型,而是另一个自定义类。
二、解决NullReferenceException的问题
你的代码抛出空引用异常的核心原因是:当传入的user对象的Department属性为null时,表达式直接尝试访问Department.Name,自然会触发异常。下面给你两种解决方案:
方案1:提前实例化Department
在调用编译后的表达式之前,手动确保user.Department已经被初始化:
// 初始化User和它的Department User user = new User(); user.Department = new Department(); // 再调用编译后的表达式 compiledExpression(user);
方案2:在表达式中自动处理null情况
如果你希望表达式能自动处理Department为null的场景,可以通过Expression.Condition和Expression.Block来实现——先检查Department是否为null,若为null则先创建实例并赋值,再给Name属性赋值。修改后的代码如下:
ParameterExpression paramExpr = Expression.Parameter(typeof(User), "user"); MemberExpression depPropExpr = MemberExpression.Property(paramExpr, "Department"); // 创建Department实例的表达式 NewExpression newDepExpr = Expression.New(typeof(Department)); // 条件表达式:如果Department为null,就赋值新实例,否则保留原实例 ConditionalExpression ensureDepExpr = Expression.Condition( Expression.Equal(depPropExpr, Expression.Constant(null)), Expression.Assign(depPropExpr, newDepExpr), depPropExpr ); // 基于确保非null的Department获取Name属性 MemberExpression depNamePropExpr = MemberExpression.Property(ensureDepExpr, "Name"); ConstantExpression constantExpression = Expression.Constant("SBCA"); var assignNameExpr = Expression.Assign(depNamePropExpr, constantExpression); // 用Block表达式按顺序执行:先确保Department存在,再赋值Name var blockExpr = Expression.Block(ensureDepExpr, assignNameExpr); var compiledExpression = Expression.Lambda<Action<User>>(blockExpr, new[] { paramExpr }).Compile(); // 现在即使user.Department为null也能正常执行 User user = new User(); compiledExpression(user);
这个方案的好处是不需要提前手动初始化Department,表达式会自动处理null的情况,逻辑更健壮。
内容的提问来源于stack exchange,提问作者Frylle Bancaso
相关产品推荐
相关产品推荐

