简体   繁体   中英

C#: Get a child class's nested type by name, when that child class inherits from a base class that holds those nested types

First off, I fully realize this is a bit strange and probably not optimal, but I'm still looking for a way to do it :)

I have a class similar to this:

public class Fruit {
  public class Seed { } 
  public class Pit { } 
}

Then I have a subclass that inherits:

public class Avocado : Fruit {}

Elsewhere in the code, I have a string that says "Avocado.Pit", and I need to get that exact Type.

typeof(Fruit).GetNestedTypes() does in fact contain Seed and Pit , but typeof(Avocado).GetNestedTypes() returns empty though, as Seed and Pit are on Fruit , not on Avocado (this is expected: even though Avocado inherits from Fruit , the documentation for GetNestedTypes() mentions that nested classes that come from the base type are omitted). If I manually try new Avocado.Pit(); or SomeGenericMethod<Avocado.Pit>(); , it does work as expected, so it seems like this should be possible.

So how can I do something like:

System.Type desiredType = System.Type.GetNestedTypesIncludingInherited("Avocado.Pit");
// desiredType.FullName would be Avocado.Pit, not Fruit.Pit.

I expect the real way will require a few more hoops to jump through, but that's fine; is this possible? Thanks very much!

The program below will print your nested types:

TypeExample.Avocado+Peel

TypeExample.Fruit+Seed

TypeExample.Fruit+Pit

TypeExample.Fruit+Seed+InnerSeed

using System;
using System.Collections.Generic;
using System.Linq;

namespace TypeExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var type = typeof(Avocado);
            var types = type.RetrieveNestedTypes();

            foreach (var innerType in types)
            {
                Console.WriteLine(innerType.FullName);
            }

            Console.ReadKey();
        }
    }

    public class Fruit
    {
        public class Seed
        {
            public class InnerSeed { }
        }
        public class Pit { }
    }

    public class Avocado : Fruit
    {
        public class Peel { }
    }

    public static class TypeHelper
    {
        public static List<Type> RetrieveNestedTypes(this Type type)
        {
            List<Type> list = new List<Type>();

            list.AddRange(RetrieveNestedInnerTypes(type));

            return list;
        }

        private static List<Type> RetrieveNestedInnerTypes(Type type)
        {
            var types = type.GetNestedTypes().ToList();

            foreach (Type innerType in types.ToList())
            {
                types.AddRange(RetrieveNestedInnerTypes(innerType));
            }

            var basetype = type.BaseType;

            if (basetype != null)
            {
                types.AddRange(RetrieveNestedInnerTypes(basetype));
            }

            return types;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM