C# – How to pass objects into an attribute constructor

attributesc

I am attempting to pass objects into an Attributes constructor as follows:

[PropertyValidation(new NullOrEmptyValidatorScheme())]
public string Name { get; private set; }

With this attribute constructor:

 public PropertyValidationAttribute(IValidatorScheme validator) {
      this._ValidatorScheme = validator;
    }

The code won't compile. How can I pass an object into an attribute as above?

EDIT: Yes NullOrEmptyValidatorScheme implements IValidatorScheme.

The error: error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.

Best Answer

The values into attributes are limited to simple types; for example, basic constants (including strings) and typeof... you can't use new or other more complex code. In short; you can't do this. You can give it the type though:

[PropertyValidation(typeof(NullOrEmptyValidatorScheme)]

i.e. the PropertyValidation ctor takes a Type, and use Activator.CreateInstance inside the code to create the object. Note that you should ideally just store the string internally (AssemblyQualifiedName).

From ECMA 334v4:

§24.1.3 Attribute parameter types

The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are:

  • 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.
  • Single-dimensional arrays of the above types.

and

§24.2 Attribute specification

...

An expression E is an attribute-argument-expression if all of the following statements are true:

  • The type of E is an attribute parameter type (§24.1.3).
  • At compile-time, the value of E can be resolved to one of the following:
    • A constant value.
    • A typeof-expression (§14.5.11) specifying a non-generic type, a closed constructed type (§25.5.2), or an unbound generic type (§25.5).
    • A one-dimensional array of attribute-argument-expressions.