简体   繁体   English

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

[英]Unable to cast an object at runtime

I am learning ASP.NET MVC 5 (vNext). 我正在学习ASP.NET MVC 5(vNext)。 In an effort to do this, I'm migrating an existing app. 为了做到这一点,我正在迁移现有的应用程序。 In that app, I get a list of classes that implement a specific interface. 在该应用程序中,我获得了一个实现特定接口的类列表。 In an attempt to do this, I am using the following code: 为了做到这一点,我使用以下代码:

// 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.
}       

Unfortunately, an exception is thrown that says: "Cannot cast from source type to destination type.". 不幸的是,抛出的异常是:“无法从源类型转换为目标类型。” When I print out the full name of the type, it is System.MonoType . 当我打印出该类型的全名时,它是System.MonoType What am I doing wrong? 我究竟做错了什么?

In your code, classes is a List<Type> , that is to say these are not instances of your class, they are instances of the class Type which describes the class implementing your interface. 在您的代码中, classesList<Type> ,也就是说这些不是您的类的实例,它们是类Type实例,它描述了实现您的接口的类。

Hence this line 因此这条线

var converted = (IMyInterface)(c);

Will always throw an exception, as Type does not implement IMyInterface . 将始终抛出异常,因为Type没有实现IMyInterface I suspect what you actually wanted to do is instantiate an instance of your class using a Type which can be achieved with the static methods on Activator such as 我怀疑你真正想要做的是使用实例化您的类的实例Type可与静态方法上实现Activator ,如

var converted = (IMyInterface)Activator.CreateInstance(c);

Expanding on a comment I made on your question 扩展我对您的问题所做的评论

if (classes == null)

The above line will never evaluate true, you probably wanted to check whether the list is empty 以上行永远不会评估为true,您可能想检查列表是否为空

if (classes.Count == 0)

or, in actual fact you do not need a list here at all, remove the .ToList() and consider using 或者,实际上你根本不需要列表,删除.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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM