Search code examples
c#reflectionnested-classfieldinfo

System.Reflection GetNestetTypes All fields declared Name or value


how do i get a list of all fields within all nested classes

class AirCraft
{
    class fighterJets
    {
        public string forSeas = "fj_f18";
        public string ForLand = "fj_f15";
    }
    class helicopters 
    {
        public string openFields = "Apachi";
        public string CloseCombat = "Cobra";

    }
}

the code i am trying to use is from one of the posts here i can break this into two or three separeted lines of code and it will work the question is about the expression , and using shortest/modern code.

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

this will return fieldInfo not the names or values, and i need it more as a list of string or better a dictionary for both fields-values and names but a list will do for now.

List<string> (or dictionary) ChosenContainersNamesOrValuesOfAllNested(Type T)
{
   return a shortest syntax for that task, using lambda rather foreach
}

thanks.


Solution

  • You can just use Linq's Select extension method to get just the names:

    IEnumerable<string> GetAllFieldNames(Type type)
    {
        // uses your existing method
        return GetAllFields(type).Select(f => f.Name);
    }
    

    Or the ToDictionary extension method to construct a dictionary:

    IDictionary<string, object> GetAllFieldNamesAndValues(object instance) 
    {
        return instance.GetType()
            .GetFields()
            .ToDictionary(f => f.Name, f => f.GetValue(instance));
    }
    

    Note you will need an instance of the type to get the values. Also, this will only work for a single type, since you will need an instance of each type to get the values.

    However, if you defined your fields as static you could do this:

    class AirCraft
    {
        public class fighterJets
        {
            public static string forSeas = "fj_f18";
            public static string ForLand = "fj_f15";
        }
        public class helicopters 
        {
            public static string openFields = "Apachi";
            public static string CloseCombat = "Cobra";
    
        }
    }
    
    IEnumerable<FieldInfo> GetAllStaticFields(Type type) 
    {
        return type.GetNestedTypes().SelectMany(GetAllFields)
                   .Concat(type.GetFields(BindingFlags.Public | BindingFlags.Static));
    }
    
    
    IDictionary<string, object> GetAllStaticFieldNamesAndValues(Type type) 
    {
        return GetAllStaticFields(type)
            .ToDictionary(f => f.Name, f => f.GetValue(null));
    }
    

    This works because static fields are not bound to any instance of the class.