Ich hoffe, jemand kann mich in die richtige Richtung mit dem folgenden Problem zeigen.Erstellen Sie einen Konstruktoraufruf mit Reflection Emit, die einen Func <> als Parameter übergibt.
Ich arbeite an einem Projekt, wo die Typen mit Reflection.Emit erzeugt werden, alles funktioniert gut, bis eine Anforderung entstand, wo ich eine Func <> in einen Konstruktor eines neuen Objekts wie folgt übergeben musste.
public class SearchTerm : IEntity
{
private readonly NavigationProperty<Item> _item;
public SearchTerm()
{
_item = new NavigationProperty<Item>(() => ItemIds);
}
public string[] ItemIds { get; set; }
}
LINQPad I kann der IL-Ausgang zu sehen ist wie folgt:
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
Das Problem, das ich habe ist, dass ich nicht sicher bin, wie der Delegaten in IL zu definieren.
Ich habe das versucht folgende
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);
Dann folgt der den Delegierten zu erstellen versuchen Würfen „Nicht unterstützt Exception“ mit dem Fehler „Abgeleitete Klassen müssen eine Implementierung zur Verfügung stellen.“
var funcType = typeof(Func<,>).MakeGenericType(typeBuilder, typeof(IEnumerable<string>));
method.CreateDelegate(funcType);
Ich habe auch versucht Delegate.CreateDelegate und Dynamic verwendet, die sowohl die Art erfordern, bevor Sie sie erstellt wurden.
Jeder Vorschlag, was ich falsch machen könnte, wird sehr geschätzt.
So kippen Sie einen Delegaten erstellen, bis Sie die tatsächliche Art haben? Nur um die Class SearchTerm zu bestätigen, die ich gerade mit dem Typebuilder erzeuge, wäre es nicht möglich, _item = new NavigationProperty zu enthalten- (() => ItemIds); weil ich createType aufrufen müsste, um die Eigenschaften der Klasse im Delegaten zu verwenden. BTW danke für die Antwort –
SCB
@SCB Ich sehe nicht, warum Sie eine Instanz des Delegaten erstellen müssen, um diesen Code zu generieren. Sie müssen Code generieren, um den Delegaten zu erstellen, und nicht nur den Delegaten erstellen. – svick
OK, aber mein Konstruktor für SearchTerm erstellt eine neue NavigationProperty, und ich muss etwas an diesen Objektkonstruktoraufruf übergeben. – SCB