5

Consider the following C# class declaration:

public class MyClass {
    private enum Colours { Red, Green, Blue }
}

Which is sat in a separate class library/DLL.

Given just the typeof(MyClass) object (System.Type), is there any way to check if the class contains an enum called Colours at runtime and if so return it's corresponding System.Type object?

What I'm trying to do is write some generic code that's given the type of a class and determine if contains a specifically named enum inside and then query the values in the enum.

I know how to use Reflection to query things like GetFields, GetProperties etc. but there isn't a GetClasses or GetEnums method in System.Type.

I suspect this kind of information is in the assembly?

4
  • And also, once I have the System.Type of the enum, I know how to query the values. It's getting information about the enum itself that's the tricky bit Commented Sep 23, 2015 at 14:48
  • 4
    GetNestedType Commented Sep 23, 2015 at 14:48
  • Doh! That could be it.... later! Commented Sep 23, 2015 at 14:49
  • 1
    This is where interface should be used. Commented Sep 23, 2015 at 14:52

3 Answers 3

11

Just do:

var res = typeof(MyClass).GetNestedType("Colours", BindingFlags.NonPublic);

Test res != null to see if such type exists.

Then test res.IsEnum to see if the nested type is an enum.

Addition: If the nested type is occasionally nested public, use BindingFlags.NonPublic | BindingFlags.Public instead.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks - that just the ticket. I went through the methods in System.Type and my eyes must have glazed over that. Obvious really
Yes, probably best to check for public enums
2

I came up with following two methods:

public class MyClass {
    private enum Colours { Red, Green, Blue }

    private class Inner {
        private enum Colours { Black, White }
    }
}

class Program {
    static void Main(string[] args) {
        Type coloursType;
        // 1. enumerator
        coloursType = typeof(MyClass).EnumerateNestedTypes()
            .Where(t => t.Name == "Colours" && t.IsEnum)
            .FirstOrDefault();
        // 2. search method
        coloursType = typeof(MyClass).FindNestedType(t => t.Name == "Colours" && t.IsEnum);

        if(coloursType != null) {
            Console.WriteLine(string.Join(", ", coloursType.GetEnumNames()));
        } else {
            Console.WriteLine("Type not found");
        }
        Console.ReadKey();
    }
}

public static class Extensions {
  public static IEnumerable<Type> EnumerateNestedTypes(this Type type) {
        const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic;
        Queue<Type> toBeVisited = new Queue<Type>();
        toBeVisited.Enqueue(type);
        do {
            Type[] nestedTypes = toBeVisited.Dequeue().GetNestedTypes(flags);
            for(int i = 0, l = nestedTypes.Length; i < l; i++) {
                Type t = nestedTypes[i];
                yield return t;
                toBeVisited.Enqueue(t);
            }
        } while(toBeVisited.Count != 0);
    }

    public static Type FindNestedType(this Type type, Predicate<Type> filter) {
        const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic;
        Type[] nestedTypes = type.GetNestedTypes(flags);
        foreach(var nestedType in nestedTypes) {
            if(filter(nestedType)) {
                return nestedType;
            }
        }
        foreach(var nestedType in nestedTypes) {
            Type result = FindNestedType(nestedType, filter);
            if(result != null) {
                return result;
            }
        }
        return null;
    }
}

Comments

-1
var types = typeof(MyClass).Assembly.DefinedTypes;

foreach (var type in types)
{
    Console.WriteLine(type.Name);
}

Output:

MyClass
Colours

1 Comment

This will trigger a search in the whole assembly where MyClass is defined. I doubt it is the intended solution - "is there any way to check if the class contains an enum called Colours at runtime"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.