类型铸造的奇怪行为

时间:2014-08-29 07:06:13

标签: c# interface casting activator

我尝试从汇编中创建一些类型。该类型实现了接口IDerrivedInterface,它继承自接口IBaseInterface。所以,我要创建实现类型的实例,实现IBaseInterface

if (assembly != null)
{
     ObjTypes = assembly.GetTypes(); 
     foreach (var objType in ObjTypes)
     {
         try
         {
             var type = Activator.CreateInstance(objType);
             if (type is IBaseInterface)
             {
                  list.Add((IBaseInterface) type);                
             }
         }
         catch (Exception ex)
         {
             int a = 0;
         }
     }
}

有一种类型,它在IDerrivedInterface中实现assembly。但代码行list.Add((IBaseInterface) type)未执行。我试图调试这个:我将type is IBaseInterface添加到" Watches"那个值是True。这种行为的原因是什么?

UPD: list - 很简单List<>。我觉得没关系。没有异常被抛出。 IDerrived接口继承自IBaseInterface

interface IBaseInterface
{
//
}
interface IDerrivedInterface : IBaseInterface
{
}
//and a class in assembly:
class SomeType : IDerrivedInterface
{
}

UPD2: 程序集从某个文件夹加载。该文件夹中有几个程序集和几个其他文件。我正在使用" .dll"迭代所有文件。延期。然后我将所有类型实现IBaseInterface的对象收集到列表中。我的类型(实现IBaseInterface)和IBaseInterface的声明放在不同的程序集中。  所以,如果没有汇编(包含IBaseInterface的声明),它就可以工作。但是如果有那个程序集(并且在使用Type组装之前处理它)它就不起作用。

UPD3: 有几种不同的接口,它们实现了这种类型。而且,该类型来自某些BaseClass。它应该有效,但它没有......

这是关于另一个错误的some question,但是有一个关于在不同的上下文中访问两个程序集的问题。也许是我的情况。因为库(让它是" L1")引用了库(L2),其中放置了接口的声明。还有一个库(L3),它包含类的声明,它实现了L2的接口(这就是为什么L3也引用了L2)。所以我在L1中调试(它引用了L2)并且它加载了程序集L2和L3)。也许这就是我遇到这个问题的原因..

3 个答案:

答案 0 :(得分:1)

程序集将包含三种类型IBaseInterface,IDerrivedInterface和一个实现IDerrivedInterface的类。这条线

          var type = Activator.CreateInstance(objType);

将抛出异常,因为您无法创建interface类型的对象。因为接口类型的变量可以保存实现接口的类的对象的引用,但不能是它自己的对象。对于类的代码

        if (type is IBaseInterface)
         {
              list.Add((IBaseInterface) type);                
         }
如果列表是IBaseInterface,

将成功执行。

编辑:添加代码。

我制作了一个ClassLibrary,如下所示。

namespace ClassLibrary
{
    public interface IBaseInterface
    {
    }
    public interface IDerivedInterface : IBaseInterface
    {
    }

    public class Class1:IDerivedInterface
    {

    }
}

在另一个项目中,我按照代码执行。

        List<IBaseInterface> list = new List<IBaseInterface>();
        var assembly = System.Reflection.Assembly.LoadFrom("ClassLibrary.dll");
        if (assembly != null)
        {
            var ObjTypes = assembly.GetTypes();
            foreach (var objType in ObjTypes)
            {
                try
                {
                    var type = Activator.CreateInstance(objType);
                    if (type is IBaseInterface)
                    {
                        list.Add((IBaseInterface)type);
                    }
                }
                catch (Exception ex)
                {
                    int a = 0;
                }
            }
        }

它会抛出前两个接口的异常,并为类类型添加了一个项目。

答案 1 :(得分:0)

据我了解,问题是行list.Add((IBaseInterface) type);没有被执行。

你确定你的IDE(我想是Visual Studio)是在DEBUG而不是RELEASE上设置的吗?也许你只是没有看到它被执行。

也许你有一个例外,你可以在其他地方找到它。如果if包含TRUE,那么它必须进入if语句。

答案 2 :(得分:0)

所以我使用post-build事件解决它并且只将1 dll复制到子文件夹(其中程序搜索DLL类型)。在此之前,有几个依赖的DLL,据我所知,给我错误的行为。