我正在编写一个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;
}
- 你认为这是解决问题的正确方法吗?或者我应该将初始化结构的责任转移到应用程序逻辑而不是ConfigParser类?我知道这是更有效的,但使用反射我写这个方法只一次,并适用于每个结构。
- 我应该使用反射来调用Parse(),这样我就可以避免所有这些假设?或者您更愿意逐个类型地进行转换,以防止意外行为?
感谢您的宝贵时间。
假设您没有使用app.config/web有特定的原因。配置或其他内置配置文件。
-
我认为这归结于应用程序的其余部分正在做什么,但我个人会这样做。它允许你干净地获得返回类型,并且你不需要在堆栈中传递额外的结构。
-
反射是一个很棒的工具,但是有一些开销,所以如果类型列表是有限的,那么手动指定它们会更有效,或者交替地只反映未知的类型。此外,我会将您的
if
块更改为switch
语句,如果IL编译器可以充分优化条件块,您将获得效率。
我认为有一个更简单的解决办法。您可以使用自定义节处理程序来存储您的设置,自定义节处理程序在这里有很好的描述:http://devlicio.us/blogs/derik_whittaker/archive/2006/11/13/app-config-and-custom-configuration-sections.aspx)。