2013-05-07 57 views
5

我希望有人可以指出我正確的方向,並解決以下問題。使用Reflection Emit創建構造函數調用,它傳遞一個Func <>作爲參數

我正在使用Reflection.Emit生成類型的項目,所有工作都很好,直到出現需求時,我需要將Func <>傳遞到新對象的構造函數中,如下所示。

public class SearchTerm : IEntity 
{ 
    private readonly NavigationProperty<Item> _item; 

    public SearchTerm() 
    { 
     _item = new NavigationProperty<Item>(() => ItemIds); 
    } 
    public string[] ItemIds { get; set; } 
} 

使用Linqpad我可以看到IL輸出如下:

SearchTerm.<.ctor>b__0: 
IL_0000: ldarg.0  
IL_0001: call  UserQuery+SearchTerm.get_ItemIds 
IL_0006: stloc.0  // CS$1$0000 
IL_0007: br.s  IL_0009 
IL_0009: ldloc.0  // CS$1$0000 
IL_000A: ret   

SearchTerm..ctor: 
IL_0000: ldnull  
IL_0001: stloc.0  
IL_0002: ldarg.0  
IL_0003: call  System.Object..ctor 
IL_0008: nop   
IL_0009: nop   
IL_000A: ldarg.0  
IL_000B: ldloc.0  
IL_000C: brtrue.s IL_001D 
IL_000E: ldarg.0  
IL_000F: ldftn  UserQuery+SearchTerm.<.ctor>b__0 
IL_0015: newobj  System.Func<System.Collections.Generic.IEnumerable<System.String>>..ctor 
IL_001A: stloc.0  
IL_001B: br.s  IL_001D 
IL_001D: ldloc.0  
IL_001E: newobj  UserQuery<UserQuery+Item>+NavigationProperty`1..ctor 
IL_0023: stfld  UserQuery+SearchTerm._item 
IL_0028: nop   
IL_0029: ret 

我的問題是,我不知道如何內IL定義的代表。

我曾嘗試以下

var method = typeBuilder.DefineMethod("func", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, typeof(IEnumerable<string>), Type.EmptyTypes); 

var methodIl = method.GetILGenerator(); 
methodIl.Emit(OpCodes.Ldarg_0); 
methodIl.Emit(OpCodes.Call, dictionary["get_ItemIds"]); 
methodIl.Emit(OpCodes.Ret); 

然後試圖創建委託以下拋出「不支持例外」出現錯誤「派生類必須提供一個實現。」

var funcType = typeof(Func<,>).MakeGenericType(typeBuilder, typeof(IEnumerable<string>)); 
method.CreateDelegate(funcType); 

我也用Delegate.CreateDelegate和DynamicMethod的這兩個要求的類型在使用前已經創建嘗試。

任何有關我可能會做錯的建議都非常感謝。

回答

2

如果你想調用你的代碼,你必須使用Type s和MethodInfo s,而不是TypeBuilder s和MethodBuilder s。

所以,你需要CreateType(),然後使用該Type及其方法:

var generatedType = typeBuilder.CreateType(); 

var funcType = typeof(Func<,>).MakeGenericType(
    generatedType, typeof(IEnumerable<string>)); 
var d = generatedType.GetMethod("func").CreateDelegate(funcType); 
+0

所以你不能,直到你的實際類型創建一個委託?只是爲了確認我目前使用類型生成器生成的Class SearchTerm將不能包含_item = new NavigationProperty ((()=> ItemIds);因爲我需要調用createType來在委託中使用類的屬性。 BTW感謝您的迴應 – SCB 2013-05-07 20:49:54

+0

@SCB我不明白你爲什麼需要創建委託的實例來生成代碼。您需要生成代碼來創建委託,而不僅僅是創建委託。 – svick 2013-05-07 20:58:00

+0

好的,但我的SearchTerm的構造函數創建一個新的NavigationProperty,我需要將某些東西傳遞給該對象構造函數調用。 – SCB 2013-05-07 21:05:47

相關問題