Search code examples
c#classreflectionstatic

Get all fields from static classes inside static class with reflection


I have a static class that contains a lot of static classes. Each inner static class contains fields. I want to get all fields of all inner static classes.

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

I would like to print out the name of each inner class followed by the name and value of each field.

For example:

MyInnerClass

Field1 = "abc"

...

I have no problem with getting the name of all the classes:

var members = typeof(MyClass).GetMembers(BindingFlags.Public | BindingFlags.Static);

var str = ""; 
foreach (var member in members)
{
    str += member.Name +" ";             
}

Or the name and value of all fields in a specific class:

var fields = typeof(MyClass.MyInnerClass1).GetFields();
foreach (var field in fields)
{
    str += field.Name + "-";
    str += field.GetValue(typeof(MyClass.MyInnerClass1));
}

But how do I combine this? The names and the number of inner static classes may change.


Solution

  • Try the following

    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();
    

    The use of !type.IsAbstract is done to weed on non-static nested types. A static type in C# is generated as abstract under the hood.

    Also my solution will pick up both public and non-public members (both types and fields). I'm not sure if this was your intent or not so you may want to modify that part of my solution.