C#获取扩展基类的类列表

时间:2014-11-01 11:38:36

标签: java c# class interface annotations

感谢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的调用实际上是在另一个项目中,但是我想到了这一点并将数据包类移到了可执行项​​目中 - 好吧,这没有任何影响。

1 个答案:

答案 0 :(得分:1)

你的问题仍然不太清楚。标题说你想要找到继承的特定类型(C#相当于&#34;扩展&#34;)一个基本类型,但你发布的代码实际上创建了实例这些类型。或者,至少它会是正确的。

最大的问题只是你正在呼叫GetInterfaces(),但你似乎并没有真正处理接口问题。相反,请尝试以下代码:

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()方法,每个方法都做不同的事情。 &#34;执行&#34;汇编与&#34;呼叫&#34;不同装配与&#34;条目&#34;不同。当然,所有这些都与由该程序集中声明的类型标识的程序集不同。

最后请注意,如果基类在您正在检查的同一个程序集中,它将返回基类。这可能是也可能不是你想要的,但我想你可以自己弄清楚如果不是这样的话。 :)