Adding custom attributes using mono.cecil?

2020-06-08 14:04发布

I can't figure how to add custom attribute to a method using Mono.Cecil The attributes that I would want to add is like this :

.custom instance void [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::.ctor() = ( 01 00 00 00 ) 

Does anyone know how to add custom attributes

标签: c# mono.cecil
3条回答
不美不萌又怎样
2楼-- · 2020-06-08 14:27

I want to elaborate on Jb Evain's answer, about how to pass parameters to the attribute. For the sample, I used System.ComponentModel.BrowsableAttribute and passed the vlaue of browsable parameter to its constructor:

void AddBrowsableAttribute(
    ModuleDefinition module,
    Mono.Cecil.ICustomAttributeProvider targetMember, // Can be a PropertyDefinition, MethodDefinition or other member definitions
    bool browsable)
{
    // Your attribute type
    var attribType = typeof(System.ComponentModel.BrowsableAttribute);
    // Find your required constructor. This one has one boolean parameter.
    var constructor = attribType.GetConstructors()[0];
    var constructorRef = module.ImportReference(constructor);
    var attrib = new CustomAttribute(constructorRef);
    // The argument
    var browsableArg =
        new CustomAttributeArgument(
            module.ImportReference(typeof(bool)),
            browsable);
        attrib.ConstructorArguments.Add(browsableArg);
    targetMember.CustomAttributes.Add(attrib);
}

Also, named arguments can be added to Properties collection of the created CustomAttribute.

查看更多
男人必须洒脱
3楼-- · 2020-06-08 14:39

It's actually very easy.

ModuleDefinition module = ...;
MethodDefinition targetMethod = ...;
MethodReference attributeConstructor = module.Import(
    typeof(DebuggerHiddenAttribute).GetConstructor(Type.EmptyTypes));

targetMethod.CustomAttributes.Add(new CustomAttribute(attributeConstructor));
module.Write(...);
查看更多
爱情/是我丢掉的垃圾
4楼-- · 2020-06-08 14:44

This is my take,

MethodDefinition methodDefinition = ...;
var module = methodDefinition.DeclaringType.Module;
var attr = module.Import(typeof (System.Diagnostics.DebuggerHiddenAttribute));

var attrConstructor = attr.Resolve().Constructors.GetConstructor(false, new Type[] {});
methodDefinition.CustomAttributes.Add(new CustomAttribute(attrConstructor));

I noticed Jb Evain's snippet is slightly different. I'm not sure whether that is because is because he's using a newer version of Cecil or because I'm wrong :)

In my version of Cecil, Import returns a TypeReference, not the constructor.

查看更多
登录 后发表回答