Search code examples
c#system.reflection

Is there ANY way to convert System.Type to a user-defined class?


So I'm trying to set up a self-updating help command for my Discord bot, that's all you need to know there.
To data specifically from my commands, they all derive from my baseclass ModuleArchetype, and I'm using Reflection to get a list of all the command data to use in this self-updating list.

The magic goal here is to access the data in each of these lovely constructors I have in each command module.

static Banana()
{
    Alias = "banana";
    Summary = "bananas are cool";
}

I've successfully been able to check whether or not a Type inherits ModuleArchetype.

List<ModuleArchetype> Output = new List<ModuleArchetype>; //Modules to return
var TypeList = Assembly.GetExecutingAssembly().GetTypes();

foreach(Type t in TypeList)
{
    if(t.IsSubclassOf(typeof(ModuleArchetype)))
    {
        Console.WriteLine(t.Name); //to verify the check is working
        Output.Add(); //the issue
    }
}

But...

Output.Add(t); //Obviously doesn't work
Output.Add((ModuleArchetype)t); //Nope, doesn't work
Output.Add(t as ModuleArchetype); //Nope

How do I get this type into a form that the list will play nice with?


Solution

  • This...

    List<ModuleArchetype>
    

    ...is a list that can contain instances of classes inherit from ModuleArchetype. It is not a list of types or a list of classes themselves.

    I'm guessing that list will be utterly useless to you, since you appear to be interested in the static members, and static members are not contained in instances.

    If you need a list of types that correspond to classes that inherit from ModuleArchetype, you need

    List<Type>
    

    Once you have stored all the types in the list, you can access their static members via Reflection, like this:

    foreach (var item in list)
    {
        var properties = item.GetProperties(BindingFlags.Static | BindingFlags.Public);
    }
    

    If you want to get the Alias property of Banana, you'd end up using:

    var aliasProperty = list.Where( t => t.Name == "Banana" )
        .GetProperties(BindingFlags.Static | BindingFlags.Public)
        .Single( p => p.Name == "Alias" );
    var currentValue = aliasProperty.Invoke(null) as string;
    Console.WriteLine(currentValue); //Should be "banana"
    

    Of course, if you know you want the Alias property of Banana, it is wayyyy easier to type

    var currentValue = Banana.Alias;
    

    It is not possible to create a list where retrieving an item will give you access to static members, as the type information in the list isn't adequate for the compiler to have any idea what the unique properties or methods are for each different element.