使用反射在dll中获取某些基类型的所有类

Jus*_*tin 18 c# reflection

我有一个dll包含许多都继承自CommandBase类的类.我正在尝试使用C#中的反射来获取所有这些类(CommandA,CommandB,CommandC等)的实例,以便我可以在每个类上调用特定方法.这是我到目前为止:

//get assemblies in directory.
string folder = Path.Combine(HttpContext.Current.Server.MapPath("~/"), "bin");
var files = Directory.GetFiles(folder, "*.dll");
//load each assembly.
foreach (string file in files)
{
  var assembly = Assembly.LoadFile(file);
  if (assembly.FullName == "MyCommandProject")
  {
    foreach (var type in assembly.GetTypes())
    {
      if (!type.IsClass || type.IsNotPublic) continue;
      if(type is CommandBase)
      {
        var command = Activator.CreateInstance(type) as CommandBase;
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我有2个问题.第一个问题是"if(type is CommandBase")行给出以下警告:

给定的表达式永远不是提供的类型CommandBase.

第二个问题是我无法弄清楚如何获取实际对象的实例(CommandA,CommandB等...),仅将其转换为CommandBase是不够的.

Jef*_*don 30

这是我用于基于接口加载的方法.

private 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();
}
Run Code Online (Sandbox Code Playgroud)

这是基于基类回退的相同功能.

private static IList<T> GetInstances<T>()
{
        return (from t in Assembly.GetExecutingAssembly().GetTypes()
                       where t.BaseType == (typeof(T)) && t.GetConstructor(Type.EmptyTypes) != null
                       select (T)Activator.CreateInstance(t)).ToList();
}
Run Code Online (Sandbox Code Playgroud)

当然,需要稍微修改以指向您正在加载的引用.


Dr.*_*ice 7

更改type is CommandBasetypeof(CommandBase).IsAssignableFrom(type)


Aka*_*ava 7

你必须改变

if(type is CommandBase) 
Run Code Online (Sandbox Code Playgroud)

if(type.IsSubclassOf(typeof(CommandBase)))
Run Code Online (Sandbox Code Playgroud)

如果IsSubclassOf与IsAssignableFrom相反.也就是说,如果t1.IsSubclassOf(t2)为真,则t2.IsAssignableFrom(t1)也为真.