2012-10-10 74 views
1

我想在運行時使用反射來加載類型。下面是步驟:在C#中使用反射在運行時加載類型

  1. 負載使用Assembly.LoadFile(assemblyPath);
  2. 使用GetType方法得到類型
  3. 使用Activator.CreateInstance創建類型的實例的組件。

下面是我的代碼:我現在面臨

Assembly assembly = Assembly.LoadFile(assemblyName); 
Type type = assembly.GetType("RomanConerter.Converter"); 
object obj = Activator.CreateInstance(type); 

問題出在最後一行。我的轉換器有一個方法名稱Add。但我無法使用obj訪問此方法。

注意:我試圖在其他項目中加載的程序集,並且hasrd編碼了路徑。

任何人都可以幫助我嗎?

+0

你確定它是'RomanConerter'而不是'RomanConverter'嗎? – ThiefMaster

+0

其實它的一個自定義轉換器,只是在創建項目時出現拼寫錯誤,將在以後更改 – Jash

+0

@ThiefMaster,這告訴我這只是一個錯字......誰知道 – series0ne

回答

1

這一切都取決於

Assembly assembly = Assembly.LoadFile(assemblyName); 
Type type = assembly.GetType("RomanConerter.Converter"); 
dynamic obj = Activator.CreateInstance(type); 

obj.Add("stuff"); 
+0

我不知道這是否會工作 - 程序集正在加載LoadFile,它將其中的類型放入一個不同的加載上下文中 - 不知道這是否意味着任何引用的類型不會被強制轉換。 – fubaar

+0

而該組件是在不同的負載上下文中 - 我相信它引用的任何程序集都不是,因爲它們受制於正常的程序集加載規則 –

+0

@AndrasZoltan它仍然無法正常工作我無法繼續訪問Add方法與上面的代碼。 – Jash

0

你必須明確地投的類型,您要創建:

RomanConerter.Converter obj = (RomanConerter.Converter)Activator.CreateInstance(type); 
+1

是不會工作的。該類型在編譯時不可用。那有趣的基於字符串的演員是什麼?這不是C#。 –

+0

我不能那樣做。由於我正在加載的程序集名稱來自運行時。所以我不知道哪個程序集將被加載。這取決於使用輸入 – Jash

2

動態此:

dynamic obj = Activator.CreateInstance(type); 
+0

沒有動態不會工作,事實上它不工作 – Jash

+0

@Jash:你爲什麼說它不工作? –

+0

你能詳細解釋一下嗎?我使用動態綁定,然後我調用Add方法。像下面的 dynamic obj = Activator.CreateInstance(type); obj.Add - >但這種添加方法不可訪問。我看不到這種Add方法的任何插入提示。 – Jash

1

你有兩個選擇:dynamic或大量反射。

試試這個:

Type objType = obj.GetType(); 
objType.InvokeMember("Add", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, 
    null, obj, new object[] { /*comma-separated arguments here*/ }); 

你可以在這裏讀到它:Type.InvokeMember

1

如果你喜歡使用反射,你可以按如下方式使用它關於RomanConverter.Converter的類型是否可以在您的調用應用程序中使用(即包含您發佈的代碼)。如果是這樣,那麼你只是施放。

如果沒有 - 那麼你可以後期綁定反射的方法(如其他人所說的),或者使用dynamic,但恕我直言,你會做最好使用一個共同的基礎或接口:

/* common interface used in both your code and the external DLL */ 
public interface ICanAdd { 
    object Add(object source); 
} 

(我猜這裏的招牌)

,然後改變這個插件式你的血來:

namespace RomanConverter { 
    public class Converter : ICanAdd { 
    object Add(object source){ 
     //TODO: implement 
    } 
    } 
} 

現在,當您從Activator.CreateInstance獲取對象你只是中科院t至ICanAdd

ICanAdd obj = (ICanAdd)Activator.CreateInstance(type); 

現在您可以調用該方法。

+0

這也有效,但我喜歡@Andras Zoltan所說的東西。 – Jash

0

看來這可以通過幾種方式完成。

  1. 實現您的自定義類型的接口,並具有可在編譯時的界面。
  2. 使用dynamic關鍵字,因爲這將提供對有問題的對象的遲綁定。
0

如果你不想使用動態(或正在使用的C#的早期版本),你可以使用一些反思 - 這不是一個簡單的方法調用過於複雜:

obj.GetType().GetMethod("MethodName", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Invoke(obj, null); 
相關問題