如何使用mono.cecil添加没有默认构造函数的自定义属性

时间:2012-04-23 13:04:39

标签: c# mono.cecil

此问题与this one有关,但并非重复。 Jb在那里发布了添加自定义属性的信息,下面的代码片段可以使用:

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

targetMethod.CustomAttributes.Add(new CustomAttribute(attributeConstructor));
module.Write(...);

我想使用类似的东西,但是要添加一个自定义属性,其构造函数在其(唯一)构造函数中使用两个字符串参数,并且我想为那些(显然)指定值。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:12)

首先,您必须获得对构造函数的正确版本的引用:

MethodReference attributeConstructor = module.Import(
    typeof(MyAttribute).GetConstructor(new [] { typeof(string), typeof(string) }));

然后,您只需使用字符串参数填充自定义属性:

CustomAttribute attribute = new CustomAttribute(attributeConstructor);
attribute.ConstructorArguments.Add(
        new CustomAttributeArgument(
            module.TypeSystem.String, "Foo"));
attribute.ConstructorArguments.Add(
        new CustomAttributeArgument(
            module.TypeSystem.String, "Bar"));

答案 1 :(得分:2)

以下是如何设置自定义属性的命名参数,该属性使用它的构造函数完全绕过属性值的设置。作为注释,您不能直接设置CustomAttributeNamedArgument.Argument.Value或CustomAttributeNamedArgument.Argument,因为它们是只读的。

以下相当于设定 - [XXX(SomeNamedProperty = {some value})]

    var attribDefaultCtorRef = type.Module.Import(typeof(XXXAttribute).GetConstructor(Type.EmptyTypes));
    var attrib = new CustomAttribute(attribDefaultCtorRef);
    var namedPropertyTypeRef = type.Module.Import(typeof(YYY));
    attrib.Properties.Add(new CustomAttributeNamedArgument("SomeNamedProperty", new CustomAttributeArgument(namedPropertyTypeRef, {some value})));
    method.CustomAttributes.Add(attrib);