6
\$\begingroup\$

I wrote this recursive function to get all constants from a class and its subclasses. Can it be simplified?

private static IEnumerable<FieldInfo> GetPublicConstants(Type type)
{
    var subtypes = type.GetNestedTypes(BindingFlags.Public);

    foreach (var subtype in subtypes)
    {
        foreach (var constant in GetPublicConstants(subtype))
        {
            yield return constant;
        }
    }

    var publicStaticFields = type.GetFields(BindingFlags.Public |
         BindingFlags.Static | BindingFlags.FlattenHierarchy)
         .Where(fi => fi.IsLiteral && !fi.IsInitOnly);

    foreach (var fieldInfo in publicStaticFields)
    {
        yield return fieldInfo;
    }
}

For example, it would return 6 constants for the following class:

public static class MyClass
{
    public const string AAA = "";

    public static class A
    {
        public const string Aaaaa = "";

        public static class AB
        {
            public const string ABaaa = "";
        }
    }

    public static class B
    {
        public const string Baaa = "";
        public const string Bbbb = "";
    }

    public static class C
    {
        public const string Caaa = "";
    }
}

What I don't like is the fact I'm having 2 loops where I yield return 1 item because of inability to yield return a list of items.

\$\endgroup\$
6
\$\begingroup\$

How about this:

private static IEnumerable<FieldInfo> GetPublicConstants(Type type)
{
    return GetPublicClassConstants(type)
        .Concat(type.GetNestedTypes(BindingFlags.Public).SelectMany(GetPublicConstants));
}

private static IEnumerable<FieldInfo> GetPublicClassConstants(Type type)
{
    return type
        .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
        .Where(fi => fi.IsLiteral && !fi.IsInitOnly);
}

OR, as I do enjoy playing PGA Pro Code Golf:

private static IEnumerable<FieldInfo> GetPublicConstants(Type type)
{
    return type
        .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
        .Where(fi => fi.IsLiteral && !fi.IsInitOnly)
        .Concat(type.GetNestedTypes(BindingFlags.Public).SelectMany(GetPublicConstants));
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ sorry, didn't understand the PGA reference however 2nd solution is ace! \$\endgroup\$ – Иван Грозный Aug 20 '15 at 14:59
  • \$\begingroup\$ @Tsar "Professional Golfers Association" and code golf is the art/game of making the code as small as possible. \$\endgroup\$ – Jesse C. Slicer Aug 20 '15 at 18:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.