Я надеюсь, что кто-то может указать мне в правильном направлении со следующей проблемой.Создайте вызов конструктора, используя 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);
Затем пытаются создать делегат следующих бросков «Не поддерживается Exception» с ошибкой «Производные классы должны обеспечивать реализацию.»
var funcType = typeof(Func<,>).MakeGenericType(typeBuilder, typeof(IEnumerable<string>));
method.CreateDelegate(funcType);
Я также попытался с помощью Delegate.CreateDelegate и DynamicMethod которые оба требуют типа были созданы перед их использованием.
Любое предложение о том, что я могу делать неправильно, очень ценится.
Таким образом, вы не можете создать делегат до тех пор, пока у вас есть фактический тип? Просто чтобы подтвердить, что класс SearchTerm, который я в настоящее время генерирую с использованием typebuilder, не сможет содержать _item = new NavigationProperty- (() => ItemIds); потому что мне нужно будет вызвать createType для использования свойств класса в делегате. BTW спасибо за ответ –
SCB
@SCB Я не понимаю, зачем вам нужно создать экземпляр делегата для создания этого кода. Вам нужно сгенерировать код для создания делегата, а не просто создать делегат. – svick
OK, но мой конструктор для SearchTerm создает новый NavigationProperty, и мне нужно передать что-то в этот вызов конструктора объектов. – SCB