.net 可以从文件中读取静态值吗?

hgc7kmma  于 2022-11-19  发布在  .NET
关注(0)|答案(2)|浏览(140)

我创建了一个用于记录错误代码的C#代码。
我将错误代码硬编码为RecordIdstatic int s。

public class RecordId
{
    public static int UnknownCommand            = 100;
    public static int SoftwareVersion           = 101;
    public static int WarningError              = 110;
    public static int AbortError                = 111;
    // etc...
}

使用static int意味着我可以在代码中的任何地方执行RecordId.SoftwareVersion,我实际上不需要示例化RecordId类,这非常方便,因为我希望能够通过调用Log类记录代码不同部分的内容,而Log类也不需要示例化(它只需要将消息附加到文件中)
日志记录函数也是静态的,类似于

public class Logger
{
    public static void LogExperiment(int key, string value)
    {
        // Append key and value to a hardcoded filename
    }
}

然后从我代码中的任何地方

Logger.LogExperiment(RecordId.SoftwareVersion, "1.0");

这只会将101 1.0附加到日志文件中
我不需要类的示例,所以我可以从代码的任何地方进行日志记录。
现在,随着代码的增长,我不想每次添加新的RecordId时都修改代码,所以我希望有一个JSON文件,在其中将值加载到类中。
我将RecordId类修改为如下所示:

public class RecordIdNew
{
    public String UnknownCommand { get; set; }
    public String SoftwareVersion { get; set; }
    public String WarningError { get; set; }
    public String AbortError { get; set; }
}

我现在看到的问题是,为了从JSON文件填充这些值,我必须示例化类RecordId,而之前我将这些值用作静态int,因此我可以调用RecordId.SoftwareVersion
问题(可能有点开放)是:有没有一种方法可以保持RecordId不示例化,但访问来自JSON文件的值?
或者如果不可能,是否有其他结构允许我这样做?

0sgqnhkj

0sgqnhkj1#

您正在查找static constructor,即

// Let's have class being static if you don't want to create instances
public static class RecordId
{
    // To be on the safer side of the road, let's have readonly fields:
    // once set in the static constructor they can't be changed
    public static readonly int UnknownCommand;
    public static readonly int SoftwareVersion;
    public static readonly int WarningError;
    public static readonly int AbortError;

    // Static constructor, it will be called before the first read of any field
    static RecordId() {
        //TODO: put your logic here: read the file and assign values to the fields
    }
}

编辑:

请查看您的 * 当前设计 *,也许您正在寻找{Key, Value}对?例如Key == 100, Value == "UnknownCommand"等。
如果是您的情况,请尝试使用Dictionary

public static class RecordId {
  private static readonly Dictionary<int, string> s_Names = new();

  public IReadOnlyDictionary<int, string> Names => s_Names;

  static RecordId() {
    //TODO: Your logic here (fill in s_Names)
  }
}

使用方法:

int code = 100;

if (RecordId.Names.TryGetValue(code, out var name))
  Console.WriteLine($"{code} is {name}");
else
  Console.WriteLine("Unknown code");
9avjhtql

9avjhtql2#

假设您可以将静态C#属性或字段与JSON中的值完美匹配,则可以使用ModuleInitializerAttribute设置静态属性。

public static class RecordId
{
    public static int UnknownCommand { get; private set; }
    public static int SoftwareVersion { get; private set; }
    public static int WarningError { get; private set; }
    public static int AbortError { get; private set; }
    // etc...

        [ModuleInitializer]
        public static void Init()
        {
            // code to read JSON
            // loop over JSON fields, matching them to
            // above fields, setting their values...
        }
}

这为您提供了一种在运行时设置值的方法,在加载模块时设置一次(模块是程序集(reference)中的逻辑代码组)。
模块初始值设定项保证在对该模块的任何其他访问之前运行;因此,如果引用UnknownCommandanywhere,将获得从JSON读取的值。实际上,正如Dmitry在注解中指出的,模块init代码保证运行 period,即使模块中 * 没有其他代码 * 被访问。如果代码很慢或有错误,这可能是一个缺点,但在您这样的情况下很有用。
这 * 没有 * 为您提供动态创建属性的方法;这需要在编译之前生成代码,或者在运行时通过某种“Get”方法和静态字典访问值。
这是关于这个主题的an article,这是GitHub上的the original proposal

相关问题