无法在运行时强制转换对象

本文关键字:转换 对象 运行时 | 更新日期: 2023-09-27 17:50:25

我正在学习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.
}       
不幸的是,会抛出一个异常:"Cannot cast from source type to destination type."。当我打印出该类型的全名时,它是System.MonoType。我做错了什么?

无法在运行时强制转换对象

在您的代码中,classesList<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())