我正在学习ASP.NET MVC 5(vNext)。为了做到这一点,我正在迁移现有的应用程序。在该应用程序中,我获得了实现特定接口的类的列表。为了做到这一点,我正在使用以下代码:
// Find all classes that implement IMyInterface
var type = typeof(IMyInterface);
var classes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(y => type.IsAssignableFrom(y) && y.GetInterfaces().Contains(type))
.ToList();
if (classes == null)
Console.WriteLine("None found");
else
Console.WriteLine(classes.Count + " found.");
try {
foreach (var c in classes)
{
Console.WriteLine(c.GetType().FullName);
var converted = (IMyInterface)(c);
// Never gets here. Exception gets thrown.
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
// Prints: Cannot cast from source type to destination type.
}
不幸的是,抛出了一个异常消息:“无法从源类型转换为目标类型。”。当我打印出类型的全名时,它是
System.MonoType
。我究竟做错了什么? 最佳答案
在您的代码中,classes
是一个List<Type>
,也就是说,这些不是您的类的实例,它们是类Type
的实例,该类描述了实现您的接口的类。
因此这条线
var converted = (IMyInterface)(c);
始终会引发异常,因为
Type
不实现IMyInterface
。我怀疑您真正想做的是使用Type
实例化类的实例,这可以通过Activator
上的静态方法来实现,例如var converted = (IMyInterface)Activator.CreateInstance(c);
扩展我对您的问题的评论
if (classes == null)
上一行永远不会为true,您可能想检查列表是否为空
if (classes.Count == 0)
或者,实际上,您根本不需要此处的列表,请删除
.ToList()
并考虑使用// classes now an IEnumerable<Type> - no need for a list here.
var classes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(y => type.IsAssignableFrom(y) && y.GetInterfaces().Contains(type));
if (!classes.Any())