C# – Attribute argument must be a constant error when using an optional parameter in the attribute constructor

cnetvisual studio 2010

Can anyone explain why this code works:

public class AdministratorSettingValidationAttribute : Attribute
{
    public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType)
    {
        DataType = administratorSettingDataType;
    }

    public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType, Type enumerationType)
    {
        DataType = administratorSettingDataType;
        EnumerationType = enumerationType;
    }
}

…but refactoring it to use an optional parameter instead:

    public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType, Type enumerationType = null)
    {
        DataType = administratorSettingDataType;
        EnumerationType = enumerationType;
    }

…causes a compile time error:
"An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type".

Best Answer

UPDATE

The bug was reported in July of last year and is already fixed. The fix will appear in the next version of C#. See this Connect feedback item for details:

http://connect.microsoft.com/VisualStudio/feedback/details/574497/optional-parameter-of-type-string-in-a-attribute-constructor-cannot-be-null


That's clearly a compiler bug. Thanks for bringing it to my attention.

What is supposed to happen here is the compiler is supposed to realize that the optional value expression is implicitly converted to the formal parameter type, and then treat the expression as a constant expression of that type. What it is actually doing is treating the expression as the typeless null literal, which is wrong.

You can work around the bug by turning the constant into an explicitly typed one:

public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType, Type enumerationType = (Type)null) 

The fix is probably straightforward but I cannot promise that the fix will be in the next version of C#; I'm not sure what the schedule is like for taking non-critical bug fixes at this point.

Thanks again, and apologies for the inconvenience.