初始化泛型类字段和/或属性的有效方法



我正在编写一个ConfigParser类,它从如下结构的配置文件中读取:

[Section]
option1 = foo
option2 = 12
option3 = ;
...

读取的信息实际上存储在Dictionary

struct ConfigStruct
{
    public string option1;
    public int option2;
    public char option3 { get; set; }
    // Any other _public_ fields or properties
}
ConfigParser Cp = new ConfigParser("path/to/config/file"); // Loads content
ConfigStruct Cs = Cp.CreateInstance<ConfigStruct>("Section");
Console.WriteLine(Cs.option1); // foo
Console.WriteLine(Cs.option2.ToString()); // 12
Console.WriteLine(Cs.option3.ToString()); // ;

结构(或类,没关系)ConfigStruct是特定于应用程序的,ConfigParser类应该对它一无所知。基本上,我想解析特定选项的值,并将其存储到具有相同名称的字段/属性中。解析应该根据字段/属性类型完成。

我已经为它开发了一个存根方法:

public T CreateInstance<T>(string Section) where T : new()
{
    // Gets options dictionary from loaded data
    Dictionary<string, string> Options = this.Data[Section];
    T Result = new T();
    Type StructType = Result.GetType();
    foreach (var Field in StructType.GetFields())
    {
        if (!Options.ContainsKey(Field.Name))
            continue;
        Object Value;
        if (Field.FieldType == typeof(bool))
            Value = Boolean.Parse(Options[Field.Name]);
        else if (Field.FieldType == typeof(int))
            Value = Int32.Parse(Options[Field.Name]);
        else if (Field.FieldType == typeof(double))
            Value = Double.Parse(Options[Field.Name]);
        else if (Field.FieldType == typeof(string))
            Value = Options[Field.Name];
        else if (Field.FieldType == typeof(char))
            Value = Options[Field.Name][0];
        // Add any ifs if needed
        else { /* Handle unsupported types */ }
        Field.SetValue(Result, Value);
    }
    foreach (var Property in StructType.GetProperties())
    {
         // Do the same thing with public properties
    }
    return Result;
}
  1. 你认为这是解决问题的正确方法吗?或者我应该将初始化结构的责任转移到应用程序逻辑而不是ConfigParser类?我知道这是更有效的,但使用反射我写这个方法只一次,并适用于每个结构。
  2. 我应该使用反射来调用Parse(),这样我就可以避免所有这些假设?或者您更愿意逐个类型地进行转换,以防止意外行为?

感谢您的宝贵时间。

假设您没有使用app.config/web有特定的原因。配置或其他内置配置文件。

  1. 我认为这归结于应用程序的其余部分正在做什么,但我个人会这样做。它允许你干净地获得返回类型,并且你不需要在堆栈中传递额外的结构。

  2. 反射是一个很棒的工具,但是有一些开销,所以如果类型列表是有限的,那么手动指定它们会更有效,或者交替地只反映未知的类型。此外,我会将您的if块更改为switch语句,如果IL编译器可以充分优化条件块,您将获得效率。

我认为有一个更简单的解决办法。您可以使用自定义节处理程序来存储您的设置,自定义节处理程序在这里有很好的描述:http://devlicio.us/blogs/derik_whittaker/archive/2006/11/13/app-config-and-custom-configuration-sections.aspx)。

最新更新