2010-09-16 25 views
2

在使用Relection.Emit動態創建的類上有什麼方法可以使用擴展方法嗎?例如:在運行時程序集中使用擴展方法

class somewhere 
{ 
    somewhere() 
    { 
     // define the type here using ReflectionEmit, etc. 
     Type tableType = CreateTableType(...table parameters...); 

     var table = Activator.CreateInstance(tableType); 
     table.Shuffle(); 
    } 
} 

//... elsewhere 
public class static TableTypeExtensions 
{ 
     public static Table Shuffle(this Table t) 
     { 
      ... 
     } 
} 

但是我沒有名字「Table」的類,只有Type tableType available。
有沒有辦法解決這個問題?
謝謝

回答

3

爲您的TableType定義一個通用的基類,並在其上定義擴展方法。這樣你的擴展方法也應該可用於派生類。

+0

我更喜歡界面建議,但這也不錯。 – 2010-09-16 21:25:40

+0

同意。 Upvoted它。 – 2010-09-17 06:22:40

+0

我在最終的代碼中使用了這個。對我來說,添加功能到類比接口更有意義。 – 2010-10-19 16:23:52

4

使動態類實現一個接口(如果你想要的話是一個空的接口),向接口添加擴展。

+0

@downvoter爲什麼downvote?對於OP的問題,「是否有任何方法可以對使用Relection.Emit動態創建的類使用擴展方法?」,這是一個很好且常見的解決方案。 – 2010-09-16 22:28:37

3

讓我們看看你在問什麼。

你在問如何獲得擴展方法來操作你的對象實例。

很明顯,爲了這個工作,它必須是Table,否則你的問題是沒有意義的。

因此,只要將它轉換爲Table

var table = (Table)Activator.CreateInstance(tableType); 

,你可以打電話給你的擴展方法就好了。

+0

您不必將其轉換爲基類。擴展方法也可用於派生類型。 – 2010-09-16 21:19:57

+3

如果他通過反射來構造類型,他本身不具有作爲「類型」的派生類型,只有對象實例。 Activator.CreateInstance的結果是'object'類型。轉換隻是爲了讓編譯器識別正確的類型。 – 2010-09-16 21:21:58

+0

我認爲我的例子太簡單了。我實際上並沒有在任何地方定義Table類。 tableType由 定義recordType = moduleBuilder.DefineType(「name」); tableType = typeof(BindingList <>)。MakeGenericType(recordType); – 2010-09-17 02:11:24

0

在您的somewhere代碼中,您是否有參考類型Table?如果是這樣你可以:

Type tableType = CreateTableType(...table parameters...); 

var table = Activator.CreateInstance(tableType) as Table; 
table.Shuffle(); 
+0

你應該使用演員,而不是'as'。 – Timwi 2010-09-16 22:25:39