The attribute argument must be a persistent error when using an optional parameter in the attribute constructor

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 to use an optional parameter:

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

... causes a compile-time error: " The attribute argument must be a constant expression, a type expression, or an expression of an array expression of the attribute parameter type ."

+17
c # visual-studio-2010
Nov 28 '11 at 2:16
source share
2 answers

UPDATE

The error was registered in July last year and has already been fixed. The fix will appear in the next version of C #. See this article for more details:

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




This is clearly a compiler error. Thanks for getting my attention.

It is assumed here that the compiler must understand that an optional value expression is implicitly converted to a formal parameter type, and then treats the expression as a constant expression of this type. What he actually does is treat the expression as an unconstrained null literal, which is not true.

You can get around the error by turning the constant into an explicitly typed one:

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

The fix is ​​probably simple, but I can’t promise that the fix will be in the next version of C #; I'm not sure what a schedule is for accepting non-critical bug fixes at this point.

Thanks again and apologize for the inconvenience.

+19
Nov 28 '11 at 17:42
source share

This smells like a compiler error. Attribute classes are “special” classes so that they can be used as metadata. The C # compiler allows you to use them differently than regular classes, and therefore we can assume that there is a (partial) custom implementation in the C # compiler to compile the use of attribute classes. (Can anyone check this out for mono?)

However, I did some tests and found that only when using the attribute constructor, which sets the default value for the parameter as null without specifying a user-defined value for this attribute, does the compiler give us an error. My test code is:

 class TestAttribute : Attribute { public TestAttribute(object test = null) { } //public TestAttribute(int test = 0) { } public void TestMethod(object test = null) { } } class TestClass { public TestClass(object test = null) { } } [Test()] // crashes //[Test()] // Works when using the constructor taking an int //[Test(null)] // works class Program { static void Main(string[] args) { TestClass t = new TestClass(); // works TestAttribute a = typeof(Program).GetCustomAttributes(typeof(TestAttribute), false).Cast<TestAttribute>().First(); a.TestMethod(); // works } } 

(Tested with VS 2010 under .NET 4.0, can anyone verify this with mono?)

Note that attributes already allow you to access properties as if they were optional, so you could make your optional parameter a property (if it’s not already, and remove it from the constructor. This still allows you to write [ Test (null, MyProperty = null)]

+5
Nov 28 '11 at 3:00
source share



All Articles