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

时间:2011-09-19 10:22:09

标签: c# reflection

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

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

读取的信息实际存储在Dictionary< string,string>中。我想要实现的目标如下:

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()以便我可以避免所有这些ifs吗?或者您宁愿按类型进行转换,以防止意外行为?
  3. 感谢您的时间。

2 个答案:

答案 0 :(得分:0)

我认为有一个更简单的解决方案。您可以使用自定义部分处理程序来存储您的设置,自定义部分处理程序在此处有详细描述:http://devlicio.us/blogs/derik_whittaker/archive/2006/11/13/app-config-and-custom-configuration-sections.aspx)。

答案 1 :(得分:0)

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

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

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

相关问题