感谢 Morgano,我的问题的第一部分得到了解决..
好吧,我可以在 Java 中执行此操作,但使用 C# 执行此操作时遇到一些问题..
这是我的基类(剥离):
public abstract class Packet { }
这是我的派生类的示例(我有很多派生类):
public class Foo : Packet
{
public override void Decode(DataInputStream input)
{
throw new NotImplementedException();
}
}
浏览堆栈溢出和其他网站一段时间后,我终于找到了这个解决方案,但要么它不起作用,要么我做错了什么。
public static List<T> GetInstances<T>()
{
return (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetInterfaces().Contains(typeof(T))
&& t.GetConstructor(Type.EmptyTypes) != null
select (T)Activator.CreateInstance(t)).ToList();
}
我这样称呼:
Console.WriteLine(PacketDecoder.GetInstances<Packet>().Count + "");
并且 Count 返回 0,这表明没有任何类。
<小时/>注意:我将所有这些编写为库,因此对 GetInstaces 的调用实际上是在另一个项目中,但是我考虑了这一点并将数据包类也移至可执行项目,但这没有任何效果。
最佳答案
你的问题还是不太清楚。标题表示您想要查找继承(C# 相当于“扩展”)基本类型的特定类型,但您发布的代码实际上创建了这些类型的实例。或者,如果它是正确的,至少会是这样。
最大的问题就是您正在调用GetInterfaces()
,但您似乎并没有真正处理接口(interface)。相反,请尝试以下代码:
static List<T> GetInstances<T>()
{
return Assembly.GetExecutingAssembly()
.GetTypes().Where(type =>
typeof(T).IsAssignableFrom(type) &&
type.GetConstructor(Type.EmptyTypes) != null)
.Select(type => (T)Activator.CreateInstance(type))
.ToList();
}
请注意使用 IsAssignableFrom()
。
还有一点需要注意的是您正在检查哪个程序集。从您的帖子中不清楚哪个程序集是正确的程序集,但是 Assembly
类有一些不同的 GetXXXAssembly()
方法,每个方法都执行不同的操作。 “执行”程序集与“调用”程序集不同,与“入口”程序集不同,所有这些当然都与该程序集中声明的类型所标识的程序集不同。
最后请注意,如果基类位于您正在检查的同一程序集中,上面的代码将返回基类。这可能是也可能不是您想要的,但我假设您可以自己弄清楚如何处理(如果不是)。 :)
关于java - C# 获取扩展基类的类列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26688928/