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

时间:2010-07-28 14:09:57

标签: 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;
      }
    }
  }
}

我有2个问题。第一个问题是“if(type is CommandBase”)行给出了以下警告:

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

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

4 个答案:

答案 0 :(得分: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();
}

这是基于基类拉回的相同函数。

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();
}

当然需要稍微修改一下以指向您正在加载的引用。

答案 1 :(得分:7)

type is CommandBase更改为typeof(CommandBase).IsAssignableFrom(type)

答案 2 :(得分:7)

你必须改变

if(type is CommandBase) 

if(type.IsSubclassOf(typeof(CommandBase)))

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

答案 3 :(得分:2)

那是因为您的type变量是Type,而不是CommandBase

你想要

if(type == typeof(CommandBase))

(感谢Greg的更正)