我有一个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是不够的。
答案 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的更正)