我正在学习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.
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,抛出的异常是:"无法从源类型转换为目标类型." 当我打印出该类型的全名时,它就是System.MonoType.我究竟做错了什么?
在你的代码中,classes是一个List<Type>,也就是说这些不是你的类的实例,它们是Type描述实现你的接口的类的类的实例.
因此这条线
var converted = (IMyInterface)(c);
Run Code Online (Sandbox Code Playgroud)
将永远抛出异常,因为Type没有实现IMyInterface.我怀疑你真正想要做的是实例使用类的一个实例Type,可以与静态方法来实现Activator,如
var converted = (IMyInterface)Activator.CreateInstance(c);
Run Code Online (Sandbox Code Playgroud)
扩展我对您的问题所做的评论
if (classes == null)
Run Code Online (Sandbox Code Playgroud)
以上行永远不会评估为true,您可能想检查列表是否为空
if (classes.Count == 0)
Run Code Online (Sandbox Code Playgroud)
或者,实际上你根本不需要列表,删除.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())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
123 次 |
| 最近记录: |