Search code examples
c#reflection.emitgetconstructor

Error executing CustomAttributeBuilder with type XmlDocument


I have the following code as part of a system for generating interfaces using reflection.emit

class Class1:Attribute 
{
    public Class1(XmlDocument doc) 
    {
    }
}

var type = typeof(Class1);
var ctore = type.GetConstructor(new[] { typeof(XmlDocument) });
var cab = new CustomAttributeBuilder(ctore, new object[] { new XmlDocument() });

For reasons unknown to me, the program generates an error:

In an argument, field, or property used designer custom attribute type is invalid.


Solution

  • See remarks section of CustomAttributeBuilder documentation:

    The elements of the constructorArgs array are restricted to element types. They can be byte, sbyte, int, uint, long, ulong, float, double, String, char, bool, an enum, a type, any of the previous types that was cast to an object, or a single-dimension, zero-based array of any of the previous types.

    You cannot use XmlDocument type as a constructor argument, because its not in list. This restriction goes from C# attribute parameters restriction. See 17.1.3 Attribute parameter types section of C# specification for list of acceptable parameter types:

    • One of the following types: bool, byte, char, double, float, int, long, short, string.
    • The type object.
    • The type System.Type.
    • An enum type, provided it has public accessibility and the types in which it is nested (if any) also have public accessibility (Section 17.2).
    • Single-dimensional arrays of the above types.

    Constructor public Class1(XmlDocument doc) is completely valid for regular C# class, and you can declare it in attribute class. But you can't use it when you'll apply attribute to your code. And this is goal of any attribute class. So, despite you can declare such constructor, it makes no sense for attribute class.