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

如何创建需等待实例生成后再初始化变量的类?(C#颜色管理场景)

解决方案:让子类访问父Colorset实例的其他Category成员

问题说明

你需要构建一个颜色管理系统,Colorset类包含General和Page两个子类,希望Page能访问所属同一个Colorset实例中General的成员,同时支持在实例化Colorset时灵活设置属性——未手动设置的属性自动关联General的对应默认值。

你的初始代码存在的核心问题:非静态的General实例成员无法被Page直接访问。

初始代码示例:

public class Colorset
{
    public General General { get; set; }
    public Page Page { get; set; }
}

public class General
{
    public Color Primary = Color.FromArgb("#399ed6");
    public Color Secondary = Color.FromArgb("#fff");
    public Color Text = Color.FromArgb("#000");
}

public class Page
{
    public Color TitleBar = General.Primary; // 无法访问非静态General的成员
    public Color TitleBarText = General.Secondary;
}

你期望的实例化方式:

var colorset = new()
{
    General = new()
    {
         Primary = Color.FromArgb("#fff"),
         Secondary = Color.FromArgb("#000")
    },
    Page = new()
    {
         TitleBar = Color.FromArgb("#123")
         // 未设置TitleBarText时默认使用General.Secondary的值
    }
};

可行实现方案

方案1:构造函数注入父Colorset实例

让Page持有所属Colorset的引用,通过构造函数传入,同时用属性的getter逻辑实现默认值关联:

public class Colorset
{
    public General General { get; set; } = new General();
    public Page Page { get; set; }

    // 构造时自动给Page传入当前Colorset实例
    public Colorset()
    {
        Page = new Page(this);
    }
}

public class General
{
    public Color Primary { get; set; } = Color.FromArgb("#399ed6");
    public Color Secondary { get; set; } = Color.FromArgb("#fff");
    public Color Text { get; set; } = Color.FromArgb("#000");
}

public class Page
{
    private readonly Colorset _parentColorset;
    private Color? _titleBarText;

    // 通过构造函数接收父Colorset实例
    public Page(Colorset parent)
    {
        _parentColorset = parent;
    }

    public Color TitleBar { get; set; }
    public Color TitleBarText
    {
        get => _titleBarText ?? _parentColorset.General.Secondary;
        set => _titleBarText = value;
    }
}

实例化时完全符合你的预期语法,未设置TitleBarText会自动取General.Secondary的值:

var colorset = new Colorset
{
    General = new General
    {
         Primary = Color.FromArgb("#fff"),
         Secondary = Color.FromArgb("#000")
    },
    Page = new Page(colorset)
    {
         TitleBar = Color.FromArgb("#123")
         // TitleBarText自动使用General.Secondary的值
    }
};

方案2:在Colorset中添加同步逻辑

如果不想让Page持有父实例引用,可以在Colorset的属性setter中添加默认值同步逻辑:

public class Colorset
{
    private General _general = new General();
    private Page _page = new Page();

    public General General
    {
        get => _general;
        set
        {
            _general = value;
            // 若Page的TitleBarText未设置,同步General的Secondary值
            if (_page.TitleBarText == default)
            {
                _page.TitleBarText = _general.Secondary;
            }
        }
    }

    public Page Page
    {
        get => _page;
        set
        {
            _page = value;
            // 若Page的TitleBarText未设置,同步当前General的Secondary值
            if (_page.TitleBarText == default)
            {
                _page.TitleBarText = _general.Secondary;
            }
        }
    }
}

public class General
{
    public Color Primary { get; set; } = Color.FromArgb("#399ed6");
    public Color Secondary { get; set; } = Color.FromArgb("#fff");
    public Color Text { get; set; } = Color.FromArgb("#000");
}

public class Page
{
    public Color TitleBar { get; set; }
    public Color TitleBarText { get; set; }
}

这种方式的优势是Page无需感知父实例,但要注意:如果后续General.Secondary更新,Page.TitleBarText不会自动同步,适合不需要实时更新的场景。

方案3:延迟加载实时绑定

如果需要属性值实时同步(比如General.Secondary更新后,Page.TitleBarText自动跟着变),可以用Func<T>实现延迟获取:

public class Colorset
{
    public General General { get; set; } = new General();
    public Page Page { get; set; }

    public Colorset()
    {
        // 给Page传入获取General实例的委托
        Page = new Page(() => General);
    }
}

public class Page
{
    private readonly Func<General> _getGeneral;
    private Color? _titleBar;
    private Color? _titleBarText;

    public Page(Func<General> getGeneral)
    {
        _getGeneral = getGeneral;
    }

    public Color TitleBar
    {
        get => _titleBar ?? _getGeneral().Primary;
        set => _titleBar = value;
    }

    public Color TitleBarText
    {
        get => _titleBarText ?? _getGeneral().Secondary;
        set => _titleBarText = value;
    }
}

这种方案下,未设置的属性会实时读取General的最新值,完全满足动态关联的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 03:24:23