C# 如何在使用IL Emit动态生成的类中使用本地对象
我甚至不确定这是否可能。。在一个方法中,我创建一个动态程序集,定义一个类型,并为该类型的构造函数发出IL。此方法接受一个C# 如何在使用IL Emit动态生成的类中使用本地对象,c#,.net,reflection.emit,dynamic-assemblies,C#,.net,Reflection.emit,Dynamic Assemblies,我甚至不确定这是否可能。。在一个方法中,我创建一个动态程序集,定义一个类型,并为该类型的构造函数发出IL。此方法接受一个IEnumerable。通过为动态类定义带有IEnumerable类型参数的构造函数,可以对存在于动态程序集外部的对象进行路径引用: var ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new[] { typeof
IEnumerable。通过为动态类定义带有IEnumerable
类型参数的构造函数,可以对存在于动态程序集外部的对象进行路径引用:
var ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
new[] { typeof(IEnumerable<Action<Migration>>) });
在此之后,您将能够使用Activator
创建动态类的实例:
var type = typeBuilder.CreateType();
var args = new object[] { new List<Action<Migration>>() };
var instance = Activator.CreateInstance(type, args);
var type=typeBuilder.CreateType();
var args=新对象[]{new List()};
var instance=Activator.CreateInstance(类型,args);
通过为动态类定义带有类型为IEnumerable
的参数的构造函数,可以对存在于动态程序集外部的对象进行路径引用:
var ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
new[] { typeof(IEnumerable<Action<Migration>>) });
在此之后,您将能够使用Activator
创建动态类的实例:
var type = typeBuilder.CreateType();
var args = new object[] { new List<Action<Migration>>() };
var instance = Activator.CreateInstance(type, args);
var type=typeBuilder.CreateType();
var args=新对象[]{new List()};
var instance=Activator.CreateInstance(类型,args);
不确定这是否会让你更靠近:@CALohse它不会。我从来没有找到一种方法来直接发出对我在发出IL时所做的操作的任何类型的引用,但是所做的工作是将该操作存储在一个静态字典中,并在动态程序集中发出一个调用,以回调到一个静态函数中,该静态函数返回动态类要调用的正确操作。我必须在这里添加一个答案和代码。不确定这是否让你更接近:@CALohse它没有。我从来没有找到一种方法来直接发出对我在发出IL时所做的操作的任何类型的引用,但是所做的工作是将该操作存储在一个静态字典中,并在动态程序集中发出一个调用,以回调到一个静态函数中,该静态函数返回动态类要调用的正确操作。我必须在这里添加一个答案和代码。@CALohse上面的注释导致了相同的解决方案。问题是我不能控制动态生成的类的实例化。迁移运行程序(MSBuild目标或exe)实例化该类,并始终查找无参数构造函数。@上面的CALohse注释导致了相同的解决方案。问题是我不能控制动态生成的类的实例化。迁移运行程序(MSBuild目标或exe)实例化该类,并始终查找无参数构造函数。
.class public auto ansi beforefieldinit
MdnTest.Migration1
extends [EasyMigrator.Tests]EasyMigrator.Tests.Integration.Migrators.MigratorDotNet/ActionMigration
{
.custom instance void [Migrator.Framework]Migrator.Framework.MigrationAttribute::.ctor(int64)
= (01 00 01 00 00 00 00 00 00 00 00 00 ) // ............
// int64(1) // 0x0000000000000001
.method public hidebysig specialname rtspecialname instance void
.ctor() cil managed
{
.maxstack 8
// [14 31 - 14 66]
IL_0000: ldarg.0 // this
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<class [mscorlib]System.Action`1<class [Migrator.Framework]Migrator.Framework.Migration>>::.ctor()
IL_0006: call instance void [EasyMigrator.Tests]EasyMigrator.Tests.Integration.Migrators.MigratorDotNet/ActionMigration::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1<class [mscorlib]System.Action`1<class [Migrator.Framework]Migrator.Framework.Migration>>)
IL_000b: nop
// [14 67 - 14 68]
IL_000c: nop
// [14 69 - 14 70]
IL_000d: ret
} // end of method Migration1::.ctor
} // end of class MdnTest.Migration1
.class public auto ansi beforefieldinit
MdnTest.Migration1
extends [EasyMigrator.Tests]EasyMigrator.Tests.Integration.Migrators.MigratorDotNet/ActionMigration
{
.custom instance void [Migrator.Framework]Migrator.Framework.MigrationAttribute::.ctor(int64)
= (01 00 01 00 00 00 00 00 00 00 00 00 ) // ............
// int64(1) // 0x0000000000000001
.field private static initonly class [mscorlib]System.Collections.Generic.IEnumerable`1<class [mscorlib]System.Action`1<class [Migrator.Framework]Migrator.Framework.Migration>> _actions
.method public hidebysig specialname rtspecialname instance void
.ctor() cil managed
{
.maxstack 8
// [15 31 - 15 45]
IL_0000: ldarg.0 // this
IL_0001: ldsfld class [mscorlib]System.Collections.Generic.IEnumerable`1<class [mscorlib]System.Action`1<class [Migrator.Framework]Migrator.Framework.Migration>> MdnTest.Migration1::_actions
IL_0006: call instance void [EasyMigrator.Tests]EasyMigrator.Tests.Integration.Migrators.MigratorDotNet/ActionMigration::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1<class [mscorlib]System.Action`1<class [Migrator.Framework]Migrator.Framework.Migration>>)
IL_000b: nop
// [15 46 - 15 47]
IL_000c: nop
// [15 48 - 15 49]
IL_000d: ret
} // end of method Migration1::.ctor
} // end of class MdnTest.Migration1
var ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
new[] { typeof(IEnumerable<Action<Migration>>) });
var ilg = ctor.GetILGenerator();
ilg.Emit(OpCodes.Ldarg_0); // load 'this' onto stack
ilg.Emit(OpCodes.Ldarg_1); // load constructor argument onto the stack
ilg.Emit(OpCodes.Call, baseCtor); // call base constructor
ilg.Emit(OpCodes.Ret);
var type = typeBuilder.CreateType();
var args = new object[] { new List<Action<Migration>>() };
var instance = Activator.CreateInstance(type, args);