c#:如何枚举嵌套类和所有字段的类
本文关键字:字段 嵌套 何枚举 枚举 | 更新日期: 2023-09-27 18:17:28
我有一个大的。ini文件。欧共体:
[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的行,并将值设置为类参数中的所有字段。
类结构为:
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.
注:
- 所有的值都是字符串
- 将名称中的'('替换为'_'.
- 参数名可以包含字符串"::"。由"Ext"代替。
我找到这个任务的第一个代码。我尝试使用这个函数:代码的主要部分是
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/这听起来像是一个很好的反射候选。基本上,你会读取INI文件的每一行,根据'。’分隔符,然后尝试在你的类中找到一个匹配的属性,基于深度…如果需要,请使用该值填充它。我最近用一个表达式树做了类似的事情……对于以'分隔的每个字符串。字符,访问具有该名称的属性或字段,然后尝试在该属性上查找下一个…给出一个代码示例是相当疯狂的,但这绝对是我的方法…反射,因为模式是你的类的属性和子属性匹配INI文件中的命名约定。
解决方案找到:
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());
}
}
}