2011-04-06 44 views
2

我需要在運行時創建一個帶有ref參數的委託類型。在運行時用ref參數創建C#委託類型

如果我知道在編譯時的參數類型(一個或多個),我可以使用顯式的委託類型聲明,例如:

// S is some struct/value type, e.g. int or Guid 
delegate void VoidDelSRef (ref S s); 
Type td = typeof (VoidDelSRef); 

即類型td用於創建一個C#4表達式樹,它被編譯成一個委託。

由於我的表達式樹中的代碼修改參數s,我需要通過s作爲參考。

我支持任何類型S,所以我不能用明確的委託類型聲明,因爲我只有Type ts = typeof (S)Type tsr = ts.MakeByRefType()ref類型。

我試過使用Expression.GetActionType (tsr),但它不允許ref類型。

如何在運行時使用ref參數構建代表?

回答

2

在.NET 4中,您可以使用Expression.GetDelegateType方法。與GetActionType不同,它可以與ByRef類型正常工作。

例如爲:

// void MyDelegate(ref int arg) 
var delType = Expression.GetDelegateType(typeof(int).MakeByRefType(), 
             typeof(void)); 

如果你在.NET 3.5中,這個方法不可用。如果你想複製它的功能,我建議看看它的實現(用反編譯器)。它沒有太多依賴關係;這絕對是可行的。

+0

非常感謝,它的工作:) – MillKa 2011-04-06 20:41:34

+0

嗯,它的工作 - 差不多。 GetDelegateType創建我需要的類型。所以阿尼完全回答了我的問題。不過,我仍然有一些問題需要打電話給代表。但我仍然在分析究竟是怎麼回事。我注意到了一些GetDelegateType的意外行爲:當使用完全相同的參數多次調用時,每次調用都會返回新的類型實例,因此它們不是引用相等的。以下是更多信息:[DLR @ CodePlex - 帶Expression.GetDelegateType和用戶定義結構的錯誤](http://dlr.codeplex.com/discussions/209768)。我會回來,當我知道該問什麼:) – MillKa 2011-04-07 16:39:06

+0

我想我現在明白我的問題。在構建表達式樹的函數中,我使用'Expression.GetDelegateType()'指定委託類型。但我不能將編譯的委託轉換爲'VoidDelSRef',很可能是因爲每個GetDelegateType都返回一個新的類型實例。所以我這樣稱呼代表dlg:'s s = new S(); var dpl = new object [] {s}; dlg.DynamicInvoke(dpl); s =(S)dpl [0];'。我猜想效率略低,但現在它工作:) – MillKa 2011-04-08 18:46:22