Spero che qualcuno possa indicarmi la giusta direzione con il seguente problema.Creare una chiamata di costruttore utilizzando Reflection Emit che passa un Func <> come parametro
Sto lavorando a un progetto in cui i tipi vengono generati utilizzando Reflection.Emit, tutto ha funzionato bene fino a quando non è sorto un requisito in cui dovevo passare un Func <> in un costruttore di un nuovo oggetto come di seguito.
public class SearchTerm : IEntity
{
private readonly NavigationProperty<Item> _item;
public SearchTerm()
{
_item = new NavigationProperty<Item>(() => ItemIds);
}
public string[] ItemIds { get; set; }
}
Utilizzando LINQPad posso vedere l'output IL è il seguente:
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 problema che ho è che non sono sicuro di come definire il delegato all'interno di IL.
Ho provato quanto segue
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);
Poi cercando di creare il delegato il seguente getta "non supportato eccezione" con l'errore "Le classi derivate devono fornire un'implementazione."
var funcType = typeof(Func<,>).MakeGenericType(typeBuilder, typeof(IEnumerable<string>));
method.CreateDelegate(funcType);
ho anche provato ad utilizzare Delegate.CreateDelegate e DynamicMethod che entrambi richiedono il tipo sia stato creato prima del loro utilizzo.
Qualsiasi suggerimento su quello che potrei fare male è molto apprezzato.
quindi potete creare un delegato fino ad avere il tipo effettivo? Giusto per confermare la classe SearchTerm che sto attualmente generando utilizzando il typebuilder non sarei in grado di contenere _item = new NavigationProperty- (() => ItemIds); perché avrei bisogno di chiamare createType per utilizzare le proprietà della classe nel delegato. BTW, grazie per la risposta –
SCB
@SCB Non vedo perché sarebbe necessario creare un'istanza del delegato per generare quel codice. È necessario generare codice per creare il delegato, non solo creare il delegato. – svick
OK ma il mio costruttore per SearchTerm crea una nuova NavigationProperty e ho bisogno di passare qualcosa in quella chiamata del costruttore di oggetti. – SCB