Я пишу класс ConfigParser, который читает из файла конфигурации, структурированного так:
[Section]
option1 = foo
option2 = 12
option3 = ;
...
Прочитанная информация фактически хранится в словаре <строка, строка>. Чего я хотел бы добиться, так это:
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 (), чтобы я мог избежать всех этих ifs? Или вы предпочитаете делать эти преобразования тип за типом, чтобы предотвратить непредвиденное поведение?
Спасибо за ваше время.