有没有办法将System.Type转换为用户定义的类?

时间:2018-04-09 19:28:38

标签: c# system.reflection

所以我正在尝试为我的Discord机器人设置一个自我更新的帮助命令,这就是你需要知道的全部内容。
对于特定于我的命令的数据,它们都来自我的基类ModuleArchetype,并且我使用Reflection来获取要在此自更新列表中使用的所有命令数据的列表。

这里的神奇目标是访问每个命令模块中每个可爱构造函数中的数据。

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

我已成功检查Type是否继承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
    }
}

但是...

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

如何将此类型转换为列表与之匹配的表单?

2 个答案:

答案 0 :(得分:2)

此...

List<ModuleArchetype>

...是一个列表,可以包含从ModuleArchetype继承的 类的实例。它不是类型列表或类本身列表。

我猜这个列表对你来说完全没用,因为你似乎对静态成员感兴趣,而静态成员不包含在实例中。

如果您需要与继承自ModuleArchetype的类相对应的类型列表,则需要

List<Type>

将所有类型存储在列表中后,您可以通过Reflection访问其静态成员,如下所示:

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

如果你想获得Banana的Alias属性,你最终会使用:

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"

当然,如果你知道你想要Banana的Alias属性,那么输入的方式就更容易了

var currentValue = Banana.Alias;

无法创建一个列表,其中检索项目将允许您访问静态成员,因为列表中的类型信息不足以让编译器知道每个属性的独特属性或方法是什么不同的元素。

答案 1 :(得分:0)

您无法将类型添加到列表中,因为它是一种类型。您必须定义一个对象以将其添加到列表中。

如果您正在创建插件系统或类似的东西。建议您创建一个界面。这将能够轻松创建对象列表,并从对象中获取数据。

我用开源TCP服务器完成了这项工作,客户端可以向服务器发送命令。服务器将使用在运行时加载的插件列表来激活调用方法。

通常,我建议使用接口与命令类进行交互。通过这种方式,您和其他人创建的所有命令都将更容易理解。