Когда я пытаюсь вызвать выражение лямбда, я получаю исключение. По-видимому, это связано с тем, что лямбда генерирует частный статический метод. Как я могу достичь того, чего хочу?Вызвать вызов лямбда-выражения
static void Main(string[] args)
{
var typeBuilder = CreateTypeBuilder();
AddStaticMethodAsAProperty(typeBuilder, "StaticPublic", Return1);
AddStaticMethodAsAProperty(typeBuilder, "StaticPrivate", Return2);
AddStaticMethodAsAProperty(typeBuilder, "Lambda",() => 3);
var newType = typeBuilder.CreateType();
dynamic newObject = Activator.CreateInstance(newType);
var resultFromStatic = newObject.StaticPublic; //Ok
var resultFromStaticPrivate = newObject.StaticPrivate; //Additional information: Attempt by method 'NewType.get_StaticPrivate()' to access method 'Test.Program.Return2()' failed.
var resultFromLambda = newObject.Lambda; //failed with Additional information: Attempt by method 'NewType.get_Lambda()' to access method 'Test.Program.<Main>b__3()' failed.
}
public static void AddStaticMethodAsAProperty(TypeBuilder typeBuilder, string propertyName, Func<int> methodToAdd)
{
var propertyType = methodToAdd.Method.ReturnType;
var getPropertyMethodBuilder = typeBuilder.DefineMethod(string.Format("get_{0}", propertyName), MethodAttributes.Public | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
var getIL = getPropertyMethodBuilder.GetILGenerator();
getIL.Emit(OpCodes.Call, methodToAdd.Method);
getIL.Emit(OpCodes.Ret);
var propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, new Type[] { });
propertyBuilder.SetGetMethod(getPropertyMethodBuilder);
}
public static int Return1()
{
return 1;
}
private static int Return2()
{
return 1;
}
private static TypeBuilder CreateTypeBuilder()
{
var newTypeName = "NewType";
var newAssemblyName = new AssemblyName(newTypeName);
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(newAssemblyName, AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
var typeBuilder = moduleBuilder.DefineType(newTypeName
, TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout
, null);
return typeBuilder;
}
Что именно вы намерены положить в лямбда? Сгенерированный класс не может получить доступ к личным данным в вашей исходной сборке, поэтому только тривиальные лямбды будут работать. Вам нужно создать отдельную сборку и класс здесь или у вас есть сценарий, который может помочь вам построить деревья выражений? –
Да, что вы пытаетесь сделать здесь? Построить класс прокси во время выполнения или что-то еще? – Luaan
@ Luaan: Да, этого я и пытаюсь достичь. Во время выполнения я хочу создать тип, чей геттер «маршрутизирован», как я определил его во время компиляции. – Toto