Получить все поля из статических классов внутри статического класса с отражением
У меня есть статический класс, который содержит много статических классов. Каждый внутренний статический класс содержит поля. Я хочу получить все поля всех внутренних статических классов.
public static class MyClass
{
public static class MyInnerClass1
{
public const string Field1 = "abc";
public const string Field2 = "def";
public const string Field3 = "ghi";
}
public static class MyInnerClass2
{
public const int Field1 = 1;
public const int Field2 = 2;
public const int Field3 = 3;
}
...
}
Я хотел бы распечатать имя каждого внутреннего класса, за которым следуют имя и значение каждого поля.
Например:
MyInnerClass
Поле1 = "abc"
...
У меня нет проблем с получением имени всех классов:
var members = typeof(MyClass).GetMembers(BindingFlags.Public | BindingFlags.Static);
var str = "";
foreach (var member in members)
{
str += member.Name +" ";
}
Или имя и значение всех полей определенного класса:
var fields = typeof(MyClass.MyInnerClass1).GetFields();
foreach (var field in fields)
{
str += field.Name + "-";
str += field.GetValue(typeof(MyClass.MyInnerClass1));
}
Но как мне это совместить?
Имена и количество внутренних статических классов могут измениться.
Ответы
Ответ 1
Попробуйте выполнить
var builder = new StringBuilder();
foreach (var type in typeof(MyClass).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic))
{
if (!type.IsAbstract)
{
continue;
}
builder.AppendLine(type.Name);
foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) {
var msg = String.Format("{0} = {1}", field.Name, field.GetValue(null));
builder.AppendLine(msg);
}
}
string output = builder.ToString();
Использование !type.IsAbstract
выполняется для сорняков на нестатических вложенных типах. Статический тип в С# генерируется как abstract
под капотом.
Также мое решение подберет как public
, так и непубличные члены (оба типа и поля). Я не уверен, что это было вашим намерением или нет, поэтому вы можете изменить эту часть моего решения.
Ответ 2
Вам нужно рекурсивно пройти цикл type.GetNestedTypes()
:
IEnumerable<FieldInfo> GetAllFields(Type type) {
return type.GetNestedTypes().SelectMany(GetAllFields)
.Concat(type.GetFields());
}