如何允许仅使用 Action<Class> 方法修改类属性?

Dav*_*der 5 c# oop

我有一个处理一些 UI 内容的类,让我们调用该类和实例 UI 作为示例。

在这个类中,我将有一个 Colors 类型的对象:

public class Colors {
    public ConsoleColor Primary { get; set; } = ConsoleColor.White;
    public ConsoleColor Default { get; set;  } = ConsoleColor.Gray;
    public ConsoleColor Input { get; set; } = ConsoleColor.Gray;
    public ConsoleColor Success { get; set; } = ConsoleColor.Green;
    public ConsoleColor Error { get; set; } = ConsoleColor.Red;
    public ConsoleColor Highlight { get; set; } = ConsoleColor.Blue;
}
Run Code Online (Sandbox Code Playgroud)

在 UI 内部我有这个:

public static class UI {
    public static readonly Colors Colors = new();

    public static void ConfigureColors(Action<Colors> modification) {
        modification.Invoke(Colors);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我希望能够访问 UI 之外的 Colors 属性的 getter,如下所示:

var primaryColor = UI.Colors.Primary;
Run Code Online (Sandbox Code Playgroud)

但不是设置器...现在,这两个都起作用:

UI.ConfigureColors(colors => {
    colors.Primary = ConsoleColor.Yellow;
});

UI.Colors.Primary = ConsoleColor.Green;
Run Code Online (Sandbox Code Playgroud)

但我只想能够使用 ConfigureColors() 方法设置颜色。我认为它自然会是这样,因为我将 Colors 属性设置为只读,但它并不像我想要的那样工作。

我尝试尝试使用 Colors 类中属性的可访问性,例如将它们设置为只读或“私有集”,但我想到的所有修改都会导致这两个选项都不起作用。

Oli*_*bes 3

您可以通过声明仅 getter 属性的接口来公开颜色。然后,实现也可以有设置器:

public interface IColors
{
    ConsoleColor Primary { get; }
    ConsoleColor Default { get; }
    ConsoleColor Input { get; }
    ConsoleColor Success { get; }
    ConsoleColor Error { get; }
    ConsoleColor Highlight { get; }
}

public class Colors : IColors
{
    public ConsoleColor Primary { get; set; } = ConsoleColor.White;
    public ConsoleColor Default { get; set; } = ConsoleColor.Gray;
    public ConsoleColor Input { get; set; } = ConsoleColor.Gray;
    public ConsoleColor Success { get; set; } = ConsoleColor.Green;
    public ConsoleColor Error { get; set; } = ConsoleColor.Red;
    public ConsoleColor Highlight { get; set; } = ConsoleColor.Blue;
}
Run Code Online (Sandbox Code Playgroud)

像这样配置:

public static class UI
{
    public static readonly IColors Colors = new Colors();

    public static void ConfigureColors(Action<Colors> modification)
    {
        modification.Invoke((Colors)Colors);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

var primary = UI.Colors.Primary;       // Okay

UI.Colors.Primary = ConsoleColor.Gray; // Error CS0200  Property or indexer 
                                       // 'ConfigurableColors.IColors.Primary'
                                       // cannot be assigned to --it is read only
Run Code Online (Sandbox Code Playgroud)