通过反射从静态类中获取静态类的所有字段

问题描述 投票:0回答:3

我有一个静态类,其中包含很多静态类。每个内部静态类都包含字段。我想获取所有内部静态类的所有字段。

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;
    }
    ...
}

我想打印出每个内部类的名称,后跟每个字段的名称和值。

例如:

我的内部班级

字段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));
}

但是我该如何结合呢? 内部静态类的名称和数量可能会改变。

c# class reflection static
3个回答
18
投票

尝试以下方法

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
是为了清除非静态嵌套类型。 C# 中的静态类型在底层生成为
abstract

我的解决方案还将选取

public
和非公共成员(类型和字段)。我不确定这是否是您的意图,因此您可能需要修改我的解决方案的该部分。


12
投票

您需要递归循环

type.GetNestedTypes()
:

IEnumerable<FieldInfo> GetAllFields(Type type) {
    return type.GetNestedTypes().SelectMany(GetAllFields)
               .Concat(type.GetFields());
}

0
投票

如果假设每个类中可能有一些字段和一些嵌套类,并且嵌套级别可能不止2级:

public static IEnumerable<string> GetConstants(Type type)
{
    foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.Static))
    {
        if (member.MemberType == MemberTypes.Field)
            yield return type.GetField(member.Name).GetValue(null) as string;
        else if (member.MemberType == MemberTypes.NestedType)
        {
            foreach (var nestedField in GetConstants(type.GetNestedType(member.Name)))
                yield return nestedField;
        }
    }
}

由于多种原因,我们可能需要将层次结构附加到结果值中。假设每个类都可以有一个名为“前缀”的字段:

public static IEnumerable<string> GetConstants(Type type)
{
    var prefix = type.GetField("Prefix")?.GetValue(null) ?? type.Name;

    foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy))
    {
        if (member.Name == "Prefix")
            continue;

        if (member.MemberType == MemberTypes.Field)
            yield return $"{prefix}.{type.GetField(member.Name).GetValue(null) as string}";
        else if (member.MemberType == MemberTypes.NestedType)
        {
            foreach (var nestedField in GetConstants(type.GetNestedType(member.Name)))
                yield return $"{prefix}.{nestedField}";
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.