首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何从il生成器调用Action<string,bool>

从il生成器调用Action<string, bool>可以通过以下步骤实现:

  1. 创建一个动态方法,该方法将作为il生成器的主体。可以使用System.Reflection.Emit命名空间中的TypeBuilder和MethodBuilder类来实现。
  2. 在动态方法中创建一个局部变量,用于存储Action<string, bool>委托的实例。可以使用System.Reflection.Emit命名空间中的LocalBuilder类来实现。
  3. 使用il生成器将局部变量初始化为Action<string, bool>委托的实例。可以使用System.Reflection.Emit命名空间中的ILGenerator类来实现。
  4. 使用il生成器调用Action<string, bool>委托的Invoke方法,并传递所需的参数。可以使用System.Reflection.Emit命名空间中的EmitCall方法来实现。

下面是一个示例代码,演示了如何从il生成器调用Action<string, bool>:

代码语言:txt
复制
using System;
using System.Reflection;
using System.Reflection.Emit;

public class ILGeneratorExample
{
    public static void Main()
    {
        // 创建动态程序集
        AssemblyName assemblyName = new AssemblyName("DynamicAssembly");
        AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule");
        
        // 创建动态类型
        TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicType", TypeAttributes.Public);
        
        // 创建动态方法
        MethodBuilder methodBuilder = typeBuilder.DefineMethod("DynamicMethod", MethodAttributes.Public | MethodAttributes.Static);
        
        // 定义方法的参数
        methodBuilder.SetParameters(typeof(string), typeof(bool));
        
        // 创建il生成器
        ILGenerator ilGenerator = methodBuilder.GetILGenerator();
        
        // 创建局部变量
        LocalBuilder actionDelegate = ilGenerator.DeclareLocal(typeof(Action<string, bool>));
        
        // 初始化局部变量为Action<string, bool>委托的实例
        ilGenerator.Emit(OpCodes.Ldnull);
        ilGenerator.Emit(OpCodes.Ldftn, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(bool) }));
        ilGenerator.Emit(OpCodes.Newobj, typeof(Action<string, bool>).GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }));
        ilGenerator.Emit(OpCodes.Stloc, actionDelegate);
        
        // 调用Action<string, bool>委托的Invoke方法
        ilGenerator.Emit(OpCodes.Ldloc, actionDelegate);
        ilGenerator.Emit(OpCodes.Ldstr, "Hello, IL Generator!");
        ilGenerator.Emit(OpCodes.Ldc_I4_1);
        ilGenerator.Emit(OpCodes.Callvirt, typeof(Action<string, bool>).GetMethod("Invoke"));
        
        // 返回
        ilGenerator.Emit(OpCodes.Ret);
        
        // 创建动态类型的类型
        Type dynamicType = typeBuilder.CreateType();
        
        // 创建动态方法的委托
        Action<string, bool> dynamicMethodDelegate = (Action<string, bool>)Delegate.CreateDelegate(typeof(Action<string, bool>), dynamicType.GetMethod("DynamicMethod"));
        
        // 调用动态方法
        dynamicMethodDelegate("Hello, Action!", true);
    }
}

这个示例代码演示了如何使用il生成器从动态方法中调用Action<string, bool>委托。在示例中,我们创建了一个动态程序集、动态类型和动态方法,并使用il生成器初始化了局部变量为Action<string, bool>委托的实例。然后,我们调用了Action<string, bool>委托的Invoke方法,并传递了所需的参数。最后,我们通过创建动态类型的类型和动态方法的委托来调用动态方法。

请注意,这只是一个示例代码,实际应用中可能需要根据具体需求进行适当的修改和调整。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

怎样让1+1=3?

我们在这段程序中定义了一个作整数加法运算的Add方法,但是我希望将针对这个方法的调用转移到另一个Add2方法上,为此我定义了一个Override方法。...> originalCall, Expression targetCall); } 如下所示的输出可以看出:虽然源程序我们调用的是Add方法,实际上最终的调用被转移到Add2方法上。...我们知道通过C#编写的.NET程序在编译后会转化成IL Code,在运行时以及时编译的方式转化成机器指令。如果想“篡改”某个方法的实现,要么在JIT之前改变IL代码,要么直接修改最终的机器指令。...public static void Override(Expression originalCall, Expression targetCall) { var...Development = "Development"; public static readonly string Production = "Production"; public

62830

深入探讨 C# 和 .NET 中 asyncawait 的历史、背后的设计决策和实现细节

如果调用MoveNext并且状态为-1,我们将从逻辑上开始方法的开头。 现在是最不起眼但最重要的一行:调用生成器的Start方法。...如果异步方法以前已经被挂起,生成器将已经必须制造一个任务作为该挂起处理的一部分(我们很快将看到如何以及在哪里处理),在这种情况下,调用SetException/SetResult将完成该任务。...然而,如果异步方法以前没有挂起,则我们还没有创建任务或向调用者返回任何内容,因此生成器如何生成任务方面具有更大的灵活性。...您可以在此处看到它的发生:在IL_008b处,ReadAsync返回的Task上调用GetAwaiter()方法,然后在那个结构体awaiter实例上访问IsCompleted。...然后它创建一个指向MoveNextRunner上的Run方法的Action委托;这就是它如何能够获取一个委托,在捕获的ExecutionContext上下文中调用状态机的MoveNext。

62241

Unity性能调优手册10C#优化:GC,对象池,forforeach,string,LINQ

GC.Alloc如何产生和如何处理 在本节中,让我们首先了解哪种特定的处理会导致GC.Alloc。 New引用类型 首先,这是一个非常简单的GC.Alloc发生。...避免捕获同步上下文 保存到另一个线程的异步处理返回到调用线程的机制是同步上下文和await,前面的上下文可以通过使用捕获。...使用seal方法调用 当在Unity中使用IL2CPP作为运行环境时,方法调用使用c++类虚表机制执行,以实现类的虚拟方法调用* 6 *6 https://blog.unity.com/technology...::Speak() */, L_16); 显示了VirtFuncInvoker0::Invoke被调用,即使它不是一个虚拟方法调用,并且像虚拟方法一样进行了方法调用。...由于目前的情况,最好检查由IL2CPP生成的代码,并决定每个项目的密封修饰符的设置。 对于更可靠的直接方法调用,以及对未来IL2CPP优化的预期,将密封修饰符设置为可优化标记可能是一个好主意。

93611

多线程合集(三)---异步的那些事之自定义AsyncTaskMethodBuilder

引言         之前在上一篇文章中多线程合集(二)---异步的那些事,async和await原理抛析,我们源码去分析了async和await如何运行,以及将编译后的IL代码写成了c#代码,以及实现自定义的...Awaiter,自定义异步状态机同时将本系列的第一篇文章的自定义TaskScheduler和自定义的Awaiter结合起来,将代码跑了起来,而在c#10之后,我们可以实现自定义的异步生成器,在上一篇文章中...当然可能后续某位哥哥会用到将这些知识点串联起来使用呢,可以看到,下面我们继承了Task,实现了MyTask,此处演示效果,仅仅实现了一个构造函数以及一个GetAwaiter的方法,然后上面就是我们测试调用的...) : base(action) { Action = action; } public Task Task { get; } public Func...ICriticalNotifyCompletion { public CustomAwaiter(Func func) { Func = func; } public bool

18510

ILRuntime热更新

L#的10-20倍| 4、选择性的CLR绑定使跨域调用更快速,绑定后跨域调用的性能能达到slua的2倍左右(脚本调用GameObject之类的接口) 5、支持跨域继承 6、完整的泛型支持 7、拥有Visual...,绑定后跨域调用的性能能达到slua的2倍左右(脚本调用GameObject之类的接口) 支持跨域继承 完整的泛型支持 拥有Visual Studio的调试插件,可以实现真机源码级调试。...原理就是当IL解译器发现需要调用某个指定CLR方法时,将实际调用重定向到另外一个方法进行挟持,再在这个方法中对ILRuntime的反射的用法进行处理 代码中可以看出重定向的工作是把方法挟持下来后装到ILIntepreter...>(); //Action 的参数为一个string appdomain.DelegateManager.RegisterMethodDelegate)action)(a); }); }); } //补充 //源码中可以看到以下两种注册都是使用Action和Func进行实现的,整合后会转递给:public

2.3K30

C#编程 | 那些C#中很少人知道的科技

因为C#在微软的帮助,已经原来很简单的,到现在的很好用。在10多年前,很少人知道微软做了哪些,我在网上找了很多大神的博客,然后和很多大神聊天,知道了一些科技,所以就在这里说。...} private static void GetMethodName(Expression> action) where T : class...,这是不安全代码,栈申请空间 int* block = stackalloc int[100]; 参见:stackalloc 调用堆栈 如果需要获得调用方法的堆栈,可以使用这个文章的方法 class...在一般的函数,如 Foo ,在调用就需要使用f.Foo()的方法,方法里 this 就是 f ,如果 f == null 那么在调用方法就直接不让运行,如何到方法里的判断 f.Foo(); //如果 f...为 call,直接修改 IL 可以做出很多特殊的写法。

69810

C#扩展方法原理及其使用

所以写了这边文章,力图原理角度解释扩展方法及其使用。...不得不说.NET在这方面做得很精致,很让人钦佩,那么接下来我们来看看扩展方法的原理 3、扩展方法原理及自定义扩展方法 首先我们,先看看如何自定义扩展方法 ?...通过以上实例,我们可以知道自定义扩展方法需要做到: 必须是静态类,扩展方法也为静态方法 此方法的第一个参数指定方法所操作的类型;此参数前面必须加上 this 修饰符 在调用代码中,如何不再同一个命名空间...0 IL_0004: call bool [System.Runtime]System.Int32::TryParse(string, int32&) IL_0009:...我们看一下调用后的效果,和直接调用静态方法一样TestExtension.StringExtension::ToInt32(string) ,至此,我们已经知道了扩展方法的使用了,编译器绑定,底层调用和静态调用一直

1.5K20

编码技巧 --- 谨防闭包陷阱

引言 先不论什么是闭包,什么是闭包陷阱,我们开篇先看一段代码: static void Main(string[] args) { List lists = new List<Action...i,如下: image.png 还包含了一个匿名方法b_0:void,IL中,也可以看出,先取 c_DisplayClass0_0 的变量 i ,再调用控制台输出方法。...如下: image.png 接下来,在看一下整个控制台程序 Main 方法的IL代码: image.png 在IL_0007行,可以看到,声明创建一个 Action 后就紧接着创建了一个 c_DisplayClass0...需要注意的是,Action action = () => { Console.WriteLine(i); };这句代码只是声明了一个委托,委托绑定的是一个匿名方法,并没有真正执行,只有调用该委托的时候才真正执行...如何避免闭包陷阱 在上面的探究原理的过程中,其实也发现了追根究底的问题其实就是,在创建闭包对象的时候,引用的局部变量,在外部被修改(比如上面代码中的for 循环的变量 i 就是闭包对象的变量 i,指的是指针是同一个

13330

原 c#中闭包的实现方法

闭包即闭包是指可以包含自由(未绑定到特定对象)变量的代码块.表现出来是调用函数结束后,函数内的变量的生存周期拉长到调用者的生命。...闭包实例: class Program { static void Main(string[] args) { Action ss...生命周期bibao函数里面拉长到Main里面。 在js里面是通过函数对象之间作用域链的引用关系实现,那么在c#中又是用什么方法实现的呢?...具体的调用过程 Main中: .method private hidebysig static void Main(string[] args) cil managed { .entrypoint...起始用字段i和方法'b__0'实例化了action,因而在main中调用的时候变量已经包含在action的参数里面带过去了。通过这种方法实现了变量生命周期的延长。

1.6K60

.NET面试题解析(05)-常量、字段、属性、特性与委托

如何使用? 7. 下面的代码输出什么结果?为什么?...常量只能用于简单的类型,因为常量值是要被编译然后保存到程序集的元数据中,只支持基元类型,如int、char、stringbool、double等。...下面代码是一个非常简单的自定义委托: public delegate void ShowMessageHandler(string mes); 看看她生产的IL代码 ?...看看IL代码: ? 共享的局部变量被提升为委托类的一个字段了: 变量i的生命周期延长了; for循环结束后字段i的值是5了; 后面再次调用委托方法,肯定就是输出5了; 那该如何修正呢?...如何使用? 特性与属性是完全不相同的两个概念,只是在名称上比较相近。

81810

.NET面试题解析(05)-常量、字段、属性、特性与委托

如何使用? 7. 下面的代码输出什么结果?为什么?...常量只能用于简单的类型,因为常量值是要被编译然后保存到程序集的元数据中,只支持基元类型,如int、char、stringbool、double等。...下面代码是一个非常简单的自定义委托: public delegate void ShowMessageHandler(string mes); 看看她生产的IL代码 ?...看看IL代码: ? 共享的局部变量被提升为委托类的一个字段了: 变量i的生命周期延长了; for循环结束后字段i的值是5了; 后面再次调用委托方法,肯定就是输出5了; 那该如何修正呢?...如何使用? 特性与属性是完全不相同的两个概念,只是在名称上比较相近。

1K20
领券