Mam nadzieję, że ktoś może wskazać mi właściwy kierunek z następującym problemem.Utwórz wywołanie konstruktora, używając Emitenta odbicia, które przechodzi Func <> jako parametr
Pracuję nad projektem, w którym typy są generowane przy użyciu Reflection.Emit, wszystko działało bez zarzutu, aż pojawiło się wymaganie, gdzie muszę przekazać Func <> do konstruktora nowego obiektu, jak poniżej.
public class SearchTerm : IEntity
{
private readonly NavigationProperty<Item> _item;
public SearchTerm()
{
_item = new NavigationProperty<Item>(() => ItemIds);
}
public string[] ItemIds { get; set; }
}
Korzystanie LINQPad widzę wyjście IL jest następujący:
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
Problem mam to, że nie jestem pewien, jak zdefiniować delegata wewnątrz IL.
Próbowałem następujących
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);
Następnie próbuje stworzyć pełnomocnikowi następujące rzutów „nieobsługiwany wyjątek” z błędem „Klasy pochodne muszą zapewniać realizację.”
var funcType = typeof(Func<,>).MakeGenericType(typeBuilder, typeof(IEnumerable<string>));
method.CreateDelegate(funcType);
Próbowałem również używając Delegate.CreateDelegate i DynamicMethod których oba wymagają typu zostały stworzone przed ich użyciem.
Wszelkie sugestie dotyczące tego, co robię źle, są bardzo doceniane.
Więc nie można utworzyć delegata, dopóki masz rzeczywisty typ? Wystarczy, że potwierdzisz Class SearchTerm, który generuję obecnie przy użyciu typubuilder, nie będzie mógł zawierać _item = new NavigationProperty- (() => ItemIds); ponieważ musiałbym wywołać metodę createType, aby użyć właściwości klasy w delegacie. BTW dzięki za odpowiedź –
SCB
@SCB Nie widzę powodu, dlaczego trzeba utworzyć wystąpienie delegata do generowania tego kodu. Musisz wygenerować kod, aby utworzyć delegata, a nie tylko utworzyć delegata. – svick
OK, ale mój konstruktor dla SearchTerm tworzy nową właściwość NavigationProperty i muszę przekazać coś do wywołania konstruktora obiektów. – SCB