我正在编写一个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;
}
感谢您的时间。
答案 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或其他内置配置文件的具体原因。
我认为这取决于应用程序的其余部分正在做什么,但我个人会这样做。它允许您干净地获得返回类型,并且您不会在堆栈中传递额外的结构,而不需要它。
反射是一个很棒的工具,但有一些开销,所以如果类型列表是有限的,那么手动指定它们会更有效,或者只反映未知类型。此外,我会将您的if
块更改为switch
语句,如果IL编译器可以完全优化条件块,您将获得提高效率。