jbevain / cecil

Cecil is a library to inspect, modify and create .NET programs and libraries.
MIT License
2.74k stars 624 forks source link

Enum value in CustomAttributeArgument #950

Open prestsauce opened 4 months ago

prestsauce commented 4 months ago

I'm working within .net8.0-windows. I'm trying to write a class to a module (dll) using Mono.Cecil.

This class has 2 custom attributes on it. The first attribute has a constructor with a single string argument - no problems here. All works as expected. The second attribute has a constructor with a single enum argument.

The expected outcome should look like this:

  [CustomAttributeType1("someStringArgument")]
  [CustomAttributeType2(MyEnum.SomeValue)]
  public class MyCustomClass : MyCustomClassBase
  {
     ...
  }

The actual output looks like so:

  [CustomAttributeType1("someStringArgument")]
  [CustomAttributeType2]
  public class MyCustomClass : MyCustomClassBase
  {
     ...
  }

Essentially, the constructor is being posted inside the attribute with no arguments or even parentheses.

The code I'm using for CustomAttributeType2 is as follows:


...
assembly/module defined first
...

var enumType = module.ImportReference(typeof(MyEnum));
var attrType2Ctor = module.ImportReference(typeof(CustomAttributeType2).GetConstructor(new Type[] { typeof(MyEnum) }));
var customAttr2 = new CustomAttribute(attrType2Ctor);
customAttr2.ConstructorArguments.Add(new CustomAttributeArgument(enumType, MyEnum.SomeValue));
typeDefinition.CustomAttributes.Add(customAttr2);

I've also tried the following for the constructor argument:

customAttr2.ConstructorArguments.Add(new CustomAttributeArgument(enumType, (int)MyEnum.SomeValue));

I've tried this with other enums, and even got the following result, in which the NAME of the enum has been cut off:

  [CustomAttributeType1("someStringArgument")]
  [Custom]
  public class MyCustomClass : MyCustomClassBase
  {
     ...
  }

Any advice would be appreciated.