组合模式下二级属性自动初始化:如何无异常访问A类MemberB属性
问题:组合模式下自动初始化引用类实例
在采用组合模式的场景中,类A引用类B,类B包含若干公共属性。请问能否在每次初始化类B的属性时自动初始化类B本身?
代码示例
class A { B MemberB { get; set; } = null; // 必须保持默认值为NULL } class B { int Id { get; set; } string Name { get; set; } } var instanceA = new A(); instanceA.MemberB.Name = "Demo"; // 如何自动实例化MemberB避免异常?
限制条件
- MemberB在实际使用其属性前必须保持为NULL,无默认值;
- 语法不能大幅改动,不使用检查NULL的属性包装器;
- 仅在无需每次将实例转换为dynamic的情况下可使用DynamicObject。
解决方案
可以通过继承DynamicObject实现动态代理,在第一次访问属性时自动实例化B,完全满足所有限制条件:
实现代码
// 动态代理类,拦截属性访问并延迟初始化B public class LazyBProxy : DynamicObject { private B _target; // 处理属性获取操作 public override bool TryGetMember(GetMemberBinder binder, out object result) { // 仅在第一次访问时实例化B _target ??= new B(); // 将属性获取请求转发给真实的B实例 var property = typeof(B).GetProperty(binder.Name); result = property?.GetValue(_target) ?? default; return true; } // 处理属性赋值操作 public override bool TrySetMember(SetMemberBinder binder, object value) { // 仅在第一次赋值时实例化B _target ??= new B(); // 将属性赋值请求转发给真实的B实例 var property = typeof(B).GetProperty(binder.Name); property?.SetValue(_target, value); return true; } // 支持隐式转换为B类型,方便后续直接使用实例 public static implicit operator B(LazyBProxy proxy) { return proxy._target; } } // 修改类A的MemberB类型为代理类,默认保持null public class A { public LazyBProxy MemberB { get; set; } = null; } public class B { public int Id { get; set; } public string Name { get; set; } }
使用方式
仅需将instanceA声明为dynamic,即可保留原有语法实现自动初始化:
dynamic instanceA = new A(); instanceA.MemberB.Name = "Demo"; // 自动实例化B并完成赋值,无异常 // 后续可直接转换为B类型使用 B bInstance = instanceA.MemberB; Console.WriteLine(bInstance.Name); // 输出: Demo
符合限制条件说明
- MemberB初始为NULL:类A中MemberB默认值为null,只有在第一次访问其属性时才会触发B的实例化;
- 语法改动极小:仅修改了MemberB的类型,原有
instanceA.MemberB.Name的赋值语法完全保留; - 无需重复转换dynamic:仅在声明实例时使用dynamic,后续可通过隐式转换直接获取B的实例,无需每次转换。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

