You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用IL Emit为非标准类型(如Type)的局部变量赋值?

问题解决:IL Emit为Type类型局部变量赋值

原代码错误原因

你当前的IL代码核心错误在于:OpCodes.Ldloc是用来加载当前方法内的局部变量,但你传入的是C#层面的types变量(外部变量),IL运行时根本无法识别这个对象,直接导致程序无效。

解决方案:通过编译+反编译参考正确IL逻辑

步骤1:编写等效逻辑的普通C#方法

先写一个和目标逻辑完全一致的静态方法,让编译器帮我们生成正确的IL:

using System.Text;

public static void TestTypeAssignment()
{
    Type t = typeof(StringBuilder);
    Console.WriteLine(t);
}

步骤2:反编译查看IL代码

用ILSpy、dotnet ildasm等工具反编译该方法,得到正确的IL指令:

.method public hidebysig static void TestTypeAssignment() cil managed
{
    .maxstack 1
    .locals init ([0] class [System.Runtime]System.Type t)
    IL_0000: ldtoken [System.Text]System.Text.StringBuilder
    IL_0005: call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle)
    IL_000a: stloc.0
    IL_000b: ldloc.0
    IL_000c: call void [System.Console]System.Console::WriteLine(object)
    IL_0011: ret
}

步骤3:对照IL编写正确的Emit代码

根据反编译得到的IL,修正你的DynamicMethod代码:

using System.Reflection;
using System.Reflection.Emit;
using System.Text;

DynamicMethod dynamicMethod = new DynamicMethod("test", null, null);
var il = dynamicMethod.GetILGenerator();
LocalBuilder ilType = il.DeclareLocal(typeof(Type));

// 1. 加载StringBuilder的元数据令牌,调用GetTypeFromHandle获取Type实例
il.Emit(OpCodes.Ldtoken, typeof(StringBuilder));
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) })!);
// 2. 将Type实例存入局部变量
il.Emit(OpCodes.Stloc, ilType);
// 3. 加载局部变量并输出
il.Emit(OpCodes.Ldloc, ilType);
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new[] { typeof(object) })!);
// 4. 返回
il.Emit(OpCodes.Ret);

dynamicMethod.CreateDelegate(typeof(Action)).DynamicInvoke();

关键逻辑说明

  • 要在IL中获取Type实例,不能直接引用外部C#变量,必须通过Ldtoken指令加载目标类型的元数据令牌,再调用Type.GetTypeFromHandle方法生成Type对象。
  • 局部变量的操作必须严格遵循栈逻辑:先把值推入栈,再用Stloc存入局部变量;读取时用Ldloc把局部变量的值推入栈。

内容的提问来源于stack exchange,提问作者DamXosp4j

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:10:19