0

I am trying to extract enumerations declared in classes, doing:

class Program
{
    static void Main(string[] args)
    {

        var type = typeof(A);
        var declaredPublicMembers = type.GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly);
        var enums = declaredPublicMembers.Where(m => m.GetType().IsEnum).ToList();

        Console.WriteLine();
    }
}

public class A
{
    public enum eTest
    {
        a,
        b,
        c
    }
    public int Num { get; set; }

    public Dictionary<int,string> Dic { get; set; }
}

but my IsEnum keeps rendering false.

While debugging, upon converting the declaredPublicMembers[0] element to a System.RuntimeType, I am able to successfully check that the type is an enumeration.

But System.RuntimeType is not public, so how do I accomplish this task?

enter image description here

Veverke
  • 9,208
  • 4
  • 51
  • 95
  • Source code as text please. – Patrick Hofman Feb 20 '19 at 10:09
  • It is, the image is just for showing debugging values as well – Veverke Feb 20 '19 at 10:10
  • Not the entire source code is. – Patrick Hofman Feb 20 '19 at 10:10
  • 3
    In your code, `m` is a `MemberInfo`. `m.GetType()` therefore doesn't return the type of the member, but the type of the `MemberInfo`. A `MemberInfo` isn't an enum, so `.IsEnum` return false. – canton7 Feb 20 '19 at 10:13
  • @canton7: My problem is how to achieve IsEnum = true as I am doing while debugging. Actually declaredPublicMembers[0].GetType returns "RuntimeType" Full Name: "System.RuntimeType" so I was at the beginning expecting this to work – Veverke Feb 20 '19 at 10:14
  • 2
    Would `CodeCaster` or someone explain how is this a duplicate of the referred post ? The enum is not a property, there is no property of the enum type, there is only the declaration, and it is it that I want. – Veverke Feb 20 '19 at 10:19
  • 2
    @Veverke The enum is not a member of `A`, you need `GetNestedTypes` instead of `GetMembers`: `typeof(A).GetNestedTypes().Where(x => x.IsEnum)`. – Gabriel Negut Feb 20 '19 at 10:21
  • `var enums = declaredPublicMembers.Where(m => m is Type t && t.IsEnum).ToList();` You want to find all declared members, where that member is a `Type` (and not a method, event, field, etc), and that `Type` is an enum. – canton7 Feb 20 '19 at 10:22
  • @GabrielNegut: all right, will try that, I understand it is not a member and likely I should not be doing it that way. Nevertheless, the question here was (although a bit different than stated in the title - how can I achieve the same as I am doing in debug - which does say that the member returned from GetMembers (get members!) is an enumeration ?! – Veverke Feb 20 '19 at 10:23
  • I don't think it's correct that this was closed -- the linked answer doesn't contain the solution to the OP's question. – canton7 Feb 20 '19 at 10:23
  • The duplicate _does_ answer the question. The OP needs `declaredPublicMembers.Where(m => m.MemberType == MemberTypes.NestedType && ((Type)m).IsEnum)`. – CodeCaster Feb 20 '19 at 10:25
  • The duplicate answer doesn't contain either the string "NestedType" or the string "(Type)" – canton7 Feb 20 '19 at 10:26
  • Don't disregard the two people who actually answered your question (but had to do so in the comments) – canton7 Feb 20 '19 at 10:31
  • Ah it is probably worth mentioning: `Type` is an abstract class, which is implemented by `RuntimeType` (for Framework - it's a different class in Mono). Although you'll see `RuntimeType` in the debugger, if you're writing code just use its base class `Type`, which provides everything you need. – canton7 Feb 20 '19 at 10:32

2 Answers2

2
var type = typeof(A);
var declaredPublicMembers = type.GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly);
var enums = declaredPublicMembers.Where(m => m is Type t && t.IsEnum).ToList();

You want to find all declared members, where that member is a Type (and not a method, event, field, etc), and that Type is an enum.

While debugging, upon converting the declaredPublicMembers[0] element to a System.RuntimeType, I am able to successfully check that the type is an enumeration.

But System.RuntimeType is not public, so how do I accomplish this task?

Type is an abstract class, which is implemented by RuntimeType (for Framework - it's a different class in Mono). Although you'll see RuntimeType in the debugger, if you're writing code just use its base class Type, which provides everything you need.

Community
  • 1
  • 1
canton7
  • 37,633
  • 3
  • 64
  • 77
0

MemberInfo can describe different member types of a type. In your case, you get a "nested type". So the question is, how to get the actual type from a MemberInfo instance describing a nested type. You can do that by casting to Type, after which you can check whether that type is an enum:

declaredPublicMembers.Where(m => m.MemberType == MemberTypes.NestedType && ((Type)m).IsEnum)

But this code only handles nested enum types, not enum members in the sense of fields, properties and methods. For that, see Getting the type of a MemberInfo with reflection.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272