访问自定义 Settings-Class 中的嵌套成员

Access nested members in custom Settings-Class

提问人:Madax 提问时间:10/3/2023 最后编辑:Madax 更新时间:10/3/2023 访问量:54

问:

我以为我已经完全理解了 C# 中的类,但是我正在尝试为我的项目创建一个自定义设置类,但我就是无法正确处理。

我想要实现的目标:

  • 有一个类,该类将仅存在一次作为应用程序的设置。
  • 设置类中的值应按其在应用程序中的使用情况进行分组。
  • 可以直接在应用程序内访问值。
  • 程序设置中的值可能与要写入磁盘的对象中的值不同(例如)。
  • 能够将其保存/加载到磁盘/从磁盘加载。

实现此目的的唯一方法是在 settings 类中嵌套类并创建它们的实例吗?

对于上下文:

在启动时,Load() 从磁盘返回一个加载的磁盘(如果存在),如果不是,则返回一个具有标准值的新磁盘:

internal static class LoadedData
{
    internal static MQSettings Settings { get; set; } = Tools.Settings.Load();
    ...
    ...
}

我希望能够像这样访问成员:

string ConfigFolder = LoadedData.Settings.Foldernames.Config;
string UserTable = LoadedData.Settings.Tablenames.User;

不需要嵌套类,只需要将它们分组在一个名称下(例如 Foldernames)。 我曾希望它能像这样工作。或者有一个静态嵌套类或类似的东西。

internal class MQSettings : BaseClasses.SaveableObject
{
    public override string Filepath => StaticSettings.MQSettingsPath;

    internal List<string> MandatoryFolders { get; set; }
    internal List<string> MandatoryTables { get; set; }    

    internal class Foldernames
    {
        internal string Config { get; set; }
        internal string Backups { get; set; }
        ... more Foldernames
    }

    internal class Tablenames
    {
        internal string Members  { get; set; }
        internal string User { get; set; }
        ... more Tablenames
    }
    ....
}

我唯一能想到的就是这个,但不知何故感觉不对劲。

那么,有没有其他(或正确的)方法可以实现 MQSettings 中的字段通过 LoadedData.Settings.SomeType.Membername 进行分组和访问?

internal class MQSettings : BaseClasses.SaveableObject
{
    public override string Filepath => StaticSettings.MQSettingsPath;

    internal List<string> MandatoryFolders { get; set; }
    internal List<string> MandatoryTables { get; set; }

    internal _Foldernames Foldernames { get; set; }
    internal _Tablenames Tablenames { get; set; }


    internal class _Foldernames
    {
        internal string Config { get; set; }
        internal string Backups { get; set; }
    }

    internal class _Tablenames
    {
        internal string Members { get; set; }
        internal string User { get; set; }
    }
    ....
}

任何帮助或意见都是值得赞赏的。

编辑:

我忘了提到的是,嵌套类型也可能有嵌套类型。

例如: 数据库表的列。当然,这些表是特定于表的,并且表的名称在此处的设置中指定。

我是否必须创建嵌套类型的嵌套类型...? 假设一个表的 ID 列...:LoadedData.Settings.Database.Fieldnames.-sometable-.ID.

这就是我失去它的地方。那么使用此应用程序创建的新表呢?当然,它们有自己的列,需要保存在这里。也许在设置中有一个表格列表会更好?!我该怎么做?我想我把自己弄糊涂了。

internal class MQSettings : BaseClasses.SaveableObject
{
    internal _Foldernames Foldernames { get; set; }
    
    internal _Database Database { get; set; }

    internal class _Foldernames
    {
        internal string Config { get; set; }
        internal string Templates { get; set; }
        internal string Backups { get; set; }
    }
    

    internal class _Database
    {
        internal AppName.DataTypes.Database.Credentials? Credentials { get; set; }

        internal _Fieldnames Fieldnames { get; set; }           

        internal class _Fieldnames
        {
            internal _Table Table { get; set; }                 
                
            internal class _Table
            {
                internal string ID { get; set; }
            }        
        }              
    }
}

我如何访问这些东西? 我希望我能把自己说清楚。

C# 对象 嵌套类型

评论

0赞 Sweeper 10/3/2023
究竟是什么“感觉不对劲”?最后一个代码片段在我看来是合理的。
0赞 Sweeper 10/3/2023
“没有必要嵌套类,只是将它们分组在一个名称下”。是的,但是“将它们分组在一个名称下”正是您想要的,那么这有什么问题呢?这就像说,除了开车,我不需要驾照。
0赞 Madax 10/3/2023
@Sweeper 我猜是因为 1 件事的 2 个不同名称。感觉像一个肮脏的把戏......我猜,我本来希望只用一个名字来做一件事。“不需要嵌套类”应该清楚地表明没有任何方法或其他东西,只有值。也许有些我还不知道可以对成员进行分组。某种结构什么的......
1赞 T.S. 10/3/2023
你正在重新发明自行车。.NET Framework 具有用于配置的所有组件。XML 或 JSON。查找。软件包:System.Configuration.ConfigurationManager v7.0.0 ...........learn.microsoft.com/en-us/dotnet/core/extensions/......ConfigurationSection
0赞 Community 10/3/2023
请修剪您的代码,以便更轻松地找到您的问题。请遵循以下准则,创建一个最小的可重现示例

答:

0赞 StriplingWarrior 10/3/2023 #1

一些语言(如 TypeScript)允许您在一个地方简洁地定义带有嵌套声明的单个类型。C# 不是那样的。您必须声明每个类型,然后单独声明该类型的属性,即使您只计划将该类型用于该属性。

我建议采用这种语言和框架中使用的标准模式。我个人甚至不会费心将这些类声明为嵌套类:只需为它们提供足够的描述性名称,以避免在其命名空间中发生命名冲突。

对于真正只是一次性应用配置的内容,请查看 .NET 中提供的标准配置范例。它们可能是将配置加载到应用中的“正确”方法。尝试使用在初始化时加载自身的静态属性将使代码难以进行单元测试,并可能导致由紧密耦合引起的其他问题。

您提到在此配置中存储多个表名及其字段名。如果您的代码与这些字段名称所包含的概念紧密耦合,则此设计可能有问题。您是否正在尝试为这些字段名称更改的最终未来进行规划?如果使用像实体框架这样的 ORM,则此类更改应该只需要更改一行代码。您有什么理由想要更改每个环境的字段名称?您可能需要重新考虑系统是如何耦合的。

另一方面,也许这些表和字段是纯动态的。我编写了一些软件,旨在帮助用户针对他们配置的任何数据库架构构建查询。

如果您的配置变得非常高级/繁重,您可能需要仔细检查这是否是加载和存储它的正确方法。通常,真正的应用配置是为连接字符串等内容保留的。将更复杂的数据存储在数据库中并通过实体框架之类的东西加载它可能更合适。