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

如何在ClassA中为IInterfaceA的ListSequences属性实现延迟初始化

实现ListSequences的延迟初始化与数据加载

要在ClassA中实现ListSequences属性的延迟初始化(首次访问时才加载数据),同时满足接口的只读属性要求,推荐两种实现方式:

方式一:使用.NET内置的Lazy<T>(推荐)

Lazy<T>是.NET官方提供的懒加载工具类,自带线程安全控制,代码简洁且易维护。

修改后的ClassA代码

using System;
using System.Collections.Generic;
using System.Threading;

public interface IInterfaceA : IBase
{
    int Sequence { get; }
    IList<IInterfaceA> ListSequences { get; }
    string ApprovedBy { get; }
    DateTime ApprovedOn { get; }
}

public interface IBase
{
    string ID { get; }
    string Name { get; }
    string Notes { get; }
}

public class Base : IBase
{
    public string ID { get; }
    public string Name { get; }
    public string Notes { get; }

    public Base(string id, string name, string notes)
    {
        ID = id;
        Name = name;
        Notes = notes;
    }
}

public class ClassA : Base, IInterfaceA
{
    private readonly int _sequence;
    private readonly string _approvedBy;
    private readonly DateTime _approvedOn;
    // 懒加载字段,存储ListSequences的加载逻辑
    private readonly Lazy<IList<IInterfaceA>> _lazyListSequences;

    // 构造函数:传入加载子序列的逻辑(灵活适配不同数据源)
    public ClassA(string id, string name, string notes, int sequence, string approvedBy, DateTime approvedOn, Func<IList<IInterfaceA>> loadSequences)
        : base(id, name, notes)
    {
        _sequence = sequence;
        _approvedBy = approvedBy;
        _approvedOn = approvedOn;
        // 初始化Lazy,指定线程安全模式(ExecutionAndPublication确保仅一次执行加载逻辑)
        _lazyListSequences = new Lazy<IList<IInterfaceA>>(loadSequences, LazyThreadSafetyMode.ExecutionAndPublication);
    }

    // 重载构造函数:内置默认数据源加载逻辑
    public ClassA(string id, string name, string notes, int sequence, string approvedBy, DateTime approvedOn)
        : base(id, name, notes)
    {
        _sequence = sequence;
        _approvedBy = approvedBy;
        _approvedOn = approvedOn;
        _lazyListSequences = new Lazy<IList<IInterfaceA>>(() => LoadSequencesFromDataSource(ID), LazyThreadSafetyMode.ExecutionAndPublication);
    }

    // 实现接口属性:首次访问时触发加载
    public int Sequence => _sequence;
    public string ApprovedBy => _approvedBy;
    public DateTime ApprovedOn => _approvedOn;
    public IList<IInterfaceA> ListSequences => _lazyListSequences.Value;

    // 模拟从数据源加载子序列的方法(替换为实际业务逻辑)
    private IList<IInterfaceA> LoadSequencesFromDataSource(string parentId)
    {
        // 示例:从数据库/API查询当前ClassA对应的子序列
        var sequences = new List<IInterfaceA>();
        sequences.Add(new ClassA($"{parentId}_sub1", "子序列1", "备注1", 1, "admin", DateTime.Now));
        sequences.Add(new ClassA($"{parentId}_sub2", "子序列2", "备注2", 2, "admin", DateTime.Now));
        return sequences;
    }
}

关键说明

  • Lazy<T>的Value属性首次被访问时,才会执行传入的加载委托,实现延迟初始化。
  • LazyThreadSafetyMode.ExecutionAndPublication确保多线程环境下仅执行一次加载逻辑,避免重复加载。
  • 提供两种构造函数:一种允许外部传入加载逻辑(灵活适配不同场景),另一种内置默认加载逻辑(适合固定数据源)。

方式二:手动实现双重检查锁定(自定义线程安全控制)

如果需要更精细的线程安全控制,可以手动实现双重检查锁定的懒加载逻辑:

修改后的ListSequences属性实现

public class ClassA : Base, IInterfaceA
{
    // ... 其他字段和构造函数保持不变 ...

    private IList<IInterfaceA> _listSequences;
    // 用于锁定的私有对象(避免用this锁定引发其他问题)
    private readonly object _lockObj = new object();

    public IList<IInterfaceA> ListSequences
    {
        get
        {
            // 第一次检查:未初始化才进入锁定逻辑
            if (_listSequences == null)
            {
                lock (_lockObj)
                {
                    // 第二次检查:确保锁定期间未被其他线程初始化
                    if (_listSequences == null)
                    {
                        _listSequences = LoadSequencesFromDataSource(ID);
                    }
                }
            }
            return _listSequences;
        }
    }

    // ... 其他属性和方法保持不变 ...
}

关键说明

  • 双重检查锁定避免了每次访问属性都进入锁定逻辑,兼顾性能和线程安全。
  • 使用独立的_lockObj作为锁定对象,避免因外部锁定this导致的死锁风险。

注意事项

  • 由于IInterfaceA中ListSequences定义为只读属性(仅get),因此无法通过公共 setter 赋值,只能通过懒加载的方式在首次访问时填充数据。
  • 加载逻辑需根据实际业务场景实现(如数据库查询、API调用等),示例中的LoadSequencesFromDataSource仅为模拟代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:07:03