You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

组合模式下二级属性自动初始化:如何无异常访问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

符合限制条件说明

  1. MemberB初始为NULL:类A中MemberB默认值为null,只有在第一次访问其属性时才会触发B的实例化;
  2. 语法改动极小:仅修改了MemberB的类型,原有instanceA.MemberB.Name的赋值语法完全保留;
  3. 无需重复转换dynamic:仅在声明实例时使用dynamic,后续可通过隐式转换直接获取B的实例,无需每次转换。

内容的提问来源于stack exchange,提问作者Anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:37:44