2013-06-06 1 views
0

У меня есть один большой файл .ini. e.c:C#: Как перечислить класс с вложенными классами и со всеми полями

[Globals] 
EdgeDkShadowColor = 188 196 218 
EdgeFillColor = 244 244 244 

[SysMetrics] 
ActiveCaption = 207 214 232 
Background = 58 110 165 
Btnface = 244 244 244 
... 

[Button.Checkbox] 
AccentColorHint = 250 196 88 
Bgtype = imagefile 
BorderColorHint = 29 82 129 
FillColorHint = 33 161 33 
... 

[Button.Checkbox(Checkeddisabled)] 
TextColor = 161 161 146 

[Button.Checkbox(Mixeddisabled)] 
TextColor = 161 161 146 

[Button.Checkbox(Uncheckeddisabled)] 
TextColor = 161 161 146 

И я создать статический класс. Я хочу перечислить строки .ini и установить значение для всех полей из класса Parameters.

структура Класс:

public static class Parameters 
{ 
    public static class Globals 
    { 
     public static string EdgeDkShadowColor; 
     public static string EdgeFillColor; 
     ... 
    } 

    public static class SysMetrics 
    { 
     public static string ActiveCaption; 
     public static string Background; 
     public static string Btnface; 
     ... 
    } 

    public static class Button 
    { 
     public static class Checkbox 
     { 
      public static string AccentColorHint; 
      public static string Bgtype; 
      public static string BorderColorHint; 
     } 

     public static class Checkbox_Checkeddisabled 
     { 
      public static string TextColor; 
     } 

     public static class Checkbox_Mixeddisabled 
     { 
      public static string TextColor; 
     } 

     public static class Checkbox_Uncheckeddisabled 
     { 
      public static string TextColor; 
     } 
     ... 

Как правильно перечислить все поля из класса и инициализировать их в конечном итоге получить объект:

Parameters. 
Globals. 
    EdgeDkShadowColor = "188 196 218"; 
    EdgeFillColor = "244 244 244"; 
SysMetrics. 
    ActiveCaption = "207 214 232" 
    Background = "58 110 165" 
    Btnface = "244 244 244" 
    ... 
Button. 
    Checkbox. 
     AccentColorHint = "250 196 88" 
     Bgtype = "imagefile" 
     BorderColorHint = "29 82 129" 
     ...  etc. 

P.S.

  1. Все значения - это строка.
  2. '(' в имени заменяется на '_'.
  3. Название параметра может содержать строку "::". Она заменяется на "Ext".

UPDATE

я нашел первый код этой задачи я пытаюсь использовать эту функцию:. Основная часть кода

StringReader str = new StringReader(fileAsString); 
string line; 
Type curType = null; 
while ((line = str.ReadLine()) != null) 
{ 
if (string.IsNullOrEmpty(line) | line.StartsWith(";")) continue; 
if (line.Contains('[')) 
{ 
    line = line[0] + line[1].ToString().ToUpper() + line.Substring(2); 
    var listing = typeof(Parameters).GetNestedTypes().ToList(); 
    string lineS = line.Trim('[').Trim(']').Trim(')'). 
         Replace("(", "_").Replace("::", "Ext").Trim(); 
    var listingOf = listing.Find(tipe => tipe.Name == lineS); 
    curType = listingOf; 
} 
else 
{ 
    if (curType != null) 
    { 
     FieldInfo found = curType.GetField(splits[0].Trim(')').Replace("(", "_").Trim()); 
     if (found != null) 
      found.SetValue(null, splits[1].Trim()); 
    } 
} 
} 

Это работа, но только для одного уровня. Это результат работы этого кода:

http://postimg.org/image/5s28m4c8h/

+0

Вы говорите, вы хотите, чтобы заполнить объект класса, который вы сделали на основе того, что вы читали из текстового файла? – jszigeti

+0

Вы еще что-нибудь пробовали? Пожалуйста, отправьте свою первоначальную попытку и почему она не удалась. –

+0

@ p.s.w.g первый код отправлен и ждет, чтобы помочь – lasarevs

ответ

0

Решение найдено:

string bytePath = resPath + themesIni; 

if (!File.Exists(bytePath)) 
{ 
    if (foundRow != null) bytePath = resPath + @"\" + foundRow.ItemArray[1] + @"\" + themesIni; 
} 
byte[] arr = File.ReadAllBytes(bytePath); 
string fileAsString = new UnicodeEncoding().GetString(arr); 
StringReader str = new StringReader(fileAsString); 
string line; 
Type curType = null; 
Type parentType = null; 
while ((line = str.ReadLine()) != null) 
{ 
    if (string.IsNullOrEmpty(line) | line.StartsWith(";")) continue; 
    if (line.Contains('[')) 
    { 
     line = (line[0] + line[1].ToString().ToUpper() + line.Substring(2)) 
      .Trim('[').Trim(']').Trim(')').Replace("(", "_").Replace("::", "Ext").Trim(); 
     string[] splitLines = line.Split('.'); 
     //splitLines[0] = 
     // (splitLines[0][0] + splitLines[0][1].ToString().ToUpper() + splitLines[0].Substring(2)) 
     // .Trim('[').Trim(']').Trim(')').Replace("(", "_").Replace("::", "Ext").Trim(); 
     //splitLines[1] = 
     // (splitLines[1][0] + splitLines[1][1].ToString().ToUpper() + splitLines[1].Substring(2)) 
     // .Trim('[').Trim(']').Trim(')').Replace("(", "_").Replace("::", "Ext").Trim(); 
     if (splitLines.Length > 1) 
     { 
      if (parentType == null) 
      { 
       parentType = typeof(Parameters).GetNestedTypes().ToList() 
        .Find(tipe => tipe.Name == splitLines[0]); 
       List<Type> listing = parentType.GetNestedTypes().ToList(); 
       curType = listing.Find(tipe => tipe.Name == splitLines[1]); 
      } 
      else 
      { 
       List<Type> listing = parentType.GetNestedTypes().ToList(); 
       curType = listing.Find(tipe => tipe.Name == splitLines[1]); 
      } 
     } 
     else 
     { 
      parentType = null; 
      List<Type> listing = typeof (Parameters).GetNestedTypes().ToList(); 
      string lineT = line; 
      Type listingOf = listing.Find(tipe => tipe.Name == lineT); 
      curType = listingOf; 
     } 
    } 
    else 
    { 
     string[] splits = line.Split('='); 
     splits[0] = splits[0].Substring(0, 1).ToUpper() + splits[0].Substring(1); 
     if (curType != null) 
     { 
      FieldInfo found = curType.GetField(splits[0].Trim(')').Replace("(", "_").Trim()); 
      if (found != null) 
       found.SetValue(null, splits[1].Trim()); 
     } 
    } 
} 
+0

Это отражение. – Haney

0

Это звучит как хороший кандидат для размышлений. В основном вы читали каждую строку INI-файла, отслеживая глубину на основе «.». разделитель в конфигурации, затем попробуйте найти подходящее свойство в вашем классе на основе глубины ... Если вы это сделаете, заполните его значением. Я сделал что-то вроде этого с деревом выражений недавно ... Для каждой строки, разделенной символом '.' символ, получить доступ к свойству или полю с этим именем, а затем попытаться найти следующий в этом свойстве ... Образец кода будет довольно сумасшедшим, чтобы дать, но это определенно, как я подхожу к нему ... Отражение, так как шаблон что свойства и дополнительные свойства вашего класса соответствуют соглашению об именах в INI-файле.