【问题标题】:C# Getting a list of classes that extend a base classC#获取扩展基类的类列表
【发布时间】:2014-11-01 11:38:35
【问题描述】:

感谢 Morgano,我的问题的第一部分得到了解决..

好的,我可以在 Java 中执行此操作,但我在使用 C# 时遇到了一些问题..

这是我的基类(已剥离):

  public abstract class Packet { }

这是我的派生类的一个示例(我有很多):

public class Foo : Packet
{
     public override void Decode(DataInputStream input)
     {
               throw new NotImplementedException();
     }
}

浏览了stackoverflow等网站一段时间后,终于找到了这个解决方案,但是要么不行,要么是我做错了。

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

【问题讨论】:

  • Google for C# 属性
  • 谢谢,但天哪,这让我头疼,要复杂得多,而且到处都是,哈哈。
  • 更新了问题,因为现在可以理解属性部分,但是反射仍然存在问题。

标签: java c# class interface annotations


【解决方案1】:

你的问题还不是很清楚。标题说您想找到继承(C# 等效于“扩展”)基本类型的特定 types,但您发布的代码实际上创建了这些类型的 instances .或者,至少它是正确的。

最大的问题只是你调用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() 方法,每个方法都做不同的事情。 “执行”程序集与“调用”程序集不同,也与“入口”程序集不同,当然,所有这些都与由该程序集中声明的类型标识的程序集不同。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    相关资源
    最近更新 更多