2014-08-29 126 views
0

我想从程序集中创建一些类型。该类型实现了从接口IBaseInterface继承的接口IDerrivedInterface。所以,我要创建类型的实例,实现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; 
     } 
    } 
} 

有型,它实现了在assemblyIDerrivedInterface。但是代码行list.Add((IBaseInterface) type)未被执行。我试图调试:我添加type is IBaseInterface到“手表”,该值为True。这种行为的原因是什么?

UPD: list - is simple列表<>。我认为这并不重要。没有例外被抛出。 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,但有一个aswer关于在不同的上下文中访问两个程序集。也许这是我的情况。因为图书馆(让它成为“L1”)引用了图书馆(L2),在那里放置界面的声明。还有一个库(L3),它包含类的声明,它实现了L2的接口(也就是为什么L3也参考L2)。所以我正在调试L1(它有L2的参考),它加载了组件L2和L3)。也许这就是为什么我有这个问题..

+0

你是说它进入'if'块并且不会抛出异常,但'list'不包含类型? – SimpleVar 2014-08-29 07:09:53

+1

只能创建您需要**的类型的实例,不要创建所有类型的实例并选择您的需要。同时发布一些代码来重现问题。在这一刻,我们不能说出什么是错的。 – 2014-08-29 07:10:07

+0

你的“列表”是什么类型的对象? – Marwie 2014-08-29 07:10:18

回答

0

所以我解决它使用后生成事件和复制只有1 DLL到子文件夹(其中程序搜索DLL类型)。在此之前,有几个依赖的DLL,据我了解给我错误的行为。

0

据我所知,问题是行list.Add((IBaseInterface) type);没有得到执行。

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

也许你有一个例外,你可以在别的地方找到它。如果if包含TRUE,则它必须位于if语句内。

+0

它是DEBUG模式,当它处理我实现那个接口的类型时,没有例外,但它没有被添加到虽然在“手表”窗口中的条件是成立的 – Alexey 2014-08-29 08:53:09

1

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

  var type = Activator.CreateInstance(objType); 

会抛出异常,因为你不能创建类型的对象interface.Since接口类型的变量可以保存实现该接口的类的对象的引用,但不能是一个对象时,它的自我。对于班级代码

 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; 
       } 
      } 
     } 

它抛出异常用于第一两个接口,并增加了产品的类类型。

+0

是的,我明白了,但列表中没有任何项目,虽然在该程序集中键入了实现该界面的程序集 – Alexey 2014-08-29 08:52:25

+0

@Alexey我编辑了我的解决方案,并根据我的解释编写了能够成功执行的代码。 – Priyank 2014-08-29 09:10:13

+0

是的,我只是试了一下,并将接口和类的声明放在不同的库中。罚款。但在真正的项目中,它仍然没有效果。这意味着还有更多...我忽略了。例如,这种类型不是简单的实现那个接口,它是从另一个类派生的,并且更多地实现了几个接口。 – Alexey 2014-08-29 09:30:48