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

使用Reflection.Emit创建动态程序集时自定义属性添加异常

解决Reflection.Emit中MethodImplAttribute不生效的问题

我之前也踩过这个坑,你遇到的问题大概率是构造函数获取错误,或者没正确完成特性的绑定步骤。咱们一步步来排查和修复:

常见问题原因

  • 没拿到MethodImplAttribute的正确构造函数重载
  • 忘记调用MethodBuilder.SetCustomAttribute来绑定特性
  • 构造函数参数类型写错,导致获取到的构造函数为null

正确实现步骤

1. 正确获取构造函数

MethodImplAttribute最常用的是带MethodImplOptions参数的构造函数,一定要确保获取的是这个重载:

var methodImplCtor = typeof(System.Runtime.CompilerServices.MethodImplAttribute)
    .GetConstructor(new[] { typeof(System.Runtime.CompilerServices.MethodImplOptions) });

注意别写错命名空间,不然可能会获取到错误的类型或构造函数。

2. 创建特性构建器

用CustomAttributeBuilder来封装特性的构造参数,比如我们要设置MethodImplOptions.Synchronized:

var attributeBuilder = new CustomAttributeBuilder(
    methodImplCtor, 
    new object[] { System.Runtime.CompilerServices.MethodImplOptions.Synchronized });

3. 绑定到目标方法

一定要调用MethodBuilder的SetCustomAttribute方法,把特性绑定到方法上:

methodBuilder.SetCustomAttribute(attributeBuilder);

完整可运行示例

给你一个完整的代码示例,包含创建程序集、添加特性、保存和验证的全流程:

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;

class DynamicAssemblyDemo
{
    static void Main()
    {
        // 1. 创建动态程序集和模块
        var assemblyName = new AssemblyName("DynamicTestAssembly");
        var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(
            assemblyName, AssemblyBuilderAccess.RunAndSave);
        var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, "DynamicTestAssembly.dll");

        // 2. 创建类型和方法
        var typeBuilder = moduleBuilder.DefineType("TestType", TypeAttributes.Public);
        var methodBuilder = typeBuilder.DefineMethod(
            "TestMethod", 
            MethodAttributes.Public | MethodAttributes.Static, 
            typeof(void), 
            Type.EmptyTypes);

        // 3. 配置MethodImplAttribute
        var ctor = typeof(MethodImplAttribute).GetConstructor(new[] { typeof(MethodImplOptions) });
        if (ctor == null)
        {
            throw new InvalidOperationException("无法找到MethodImplAttribute的目标构造函数");
        }
        var attrBuilder = new CustomAttributeBuilder(ctor, new object[] { MethodImplOptions.NoInlining });
        methodBuilder.SetCustomAttribute(attrBuilder);

        // 4. 实现方法体(简单返回)
        var il = methodBuilder.GetILGenerator();
        il.Emit(OpCodes.Ret);

        // 5. 完成类型创建并保存程序集
        typeBuilder.CreateType();
        assemblyBuilder.Save("DynamicTestAssembly.dll");

        // 6. 加载验证特性
        var loadedAssembly = Assembly.LoadFrom("DynamicTestAssembly.dll");
        var loadedType = loadedAssembly.GetType("TestType");
        var loadedMethod = loadedType.GetMethod("TestMethod");

        var attributes = loadedMethod.GetCustomAttributes(typeof(MethodImplAttribute), false);
        if (attributes.Length > 0)
        {
            var implAttr = (MethodImplAttribute)attributes[0];
            Console.WriteLine($"成功获取到特性,配置选项:{implAttr.Value}");
        }
        else
        {
            Console.WriteLine("未找到MethodImplAttribute");
        }
    }
}

额外注意点

如果你需要使用无参构造函数,再手动设置Value属性,那就要用CustomAttributeBuilder的另一个重载,指定要设置的字段:

// 获取无参构造函数
var ctor = typeof(MethodImplAttribute).GetConstructor(Type.EmptyTypes);
// 获取Value字段
var valueField = typeof(MethodImplAttribute).GetField("Value");
// 创建特性构建器,同时设置字段值
var attrBuilder = new CustomAttributeBuilder(
    ctor, 
    new object[0], 
    new[] { valueField }, 
    new object[] { MethodImplOptions.NoOptimization });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:43:18