2014-08-29 162 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