Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attributes and Named/Optional constructor parameters not working

Tags:

I have custom attribute defined like so:

  [AttributeUsage(AttributeTargets.Field)]   public class EnumDisplayAttribute : Attribute   {     public string Description { get; private set; }     public string Code { get; private set; }      public EnumDisplayAttribute(string description = null, string code = null)     {       Description = description;       Code = code;     }   } 

Both constructor parameters are optional.

When using this attribute on a field like so

  public enum TransactionType   {     [EnumDisplay(code: "B")]      Bill,     [EnumDisplay(description: null, code: "C")]     CashReceipt,   } 

I don't see any squigglies in the code editor but I see a vague error without any File Line number of column. The error message is:

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

Clicking on the error does nothing. That is, you don't get navigated to the error site (obviously, since there is no line number and column).

even if I set up the attribute like so:

[EnumDisplay("This is a Bill")]  

The compiler doesn't like it.

Effectively, I am forced to provide both parameters (named or not) in order to use this attribute as an attribute.

Of course if I use this attribute as a regular class like so:

var enumDisplayAttribute = new EnumDisplayAttribute(); enumDisplayAttribute = new EnumDisplayAttribute(description: "This is a Bill"); enumDisplayAttribute = new EnumDisplayAttribute(code: "B"); enumDisplayAttribute = new EnumDisplayAttribute(description: "This is a Bill", code: "B"); enumDisplayAttribute = new EnumDisplayAttribute("This is a Bill", "B"); enumDisplayAttribute = new EnumDisplayAttribute("This is a Bill"); 

The compiler will accept any one of the above "styles".

Surely, I'm missing something or my brain is just not working.

like image 314
Shiv Kumar Avatar asked Nov 18 '11 22:11

Shiv Kumar


People also ask

How to pass optional parameters in c#?

By Params Keyword: You can implement optional parameters by using the params keyword. It allows you to pass any variable number of parameters to a method. But you can use the params keyword for only one parameter and that parameter is the last parameter of the method.

When to use optional parameters c#?

Optional arguments enable you to omit arguments for some parameters. Both techniques can be used with methods, indexers, constructors, and delegates. When you use named and optional arguments, the arguments are evaluated in the order in which they appear in the argument list, not the parameter list.

Can we pass multiple optional parameters in C#?

One more ways we can implement optional parameters is using method overloading. Method overloading allows us to create multiple definitions of same method with different parameters. If you're new to method overloading, read Method Overloading In C#.

What are named parameters in C#?

Named parameters provides us the relaxation to remember or to look up the order of parameters in the parameter lists of called methods. The parameter for each argument can be specified by parameter name. Using named parameters in C#, we can put any parameter in any sequence as long as the name is there.


1 Answers

Optional parameters were added to C# after optional values for attributes already existed in C#. Therefore, for optional attribute parameters, you should fall back to the attribute-specific syntax:

[AttributeUsage(AttributeTargets.Field)] public class EnumDisplayAttribute : Attribute {     public string Description { get; set; }     public string Code { get; set; }      public EnumDisplayAttribute()     {     } }  public enum TransactionType {     [EnumDisplay(Code = "B")]      Bill,     [EnumDisplay(Description = null, Code = "C")]     CashReceipt, } 

As you see, the end-result is effectively the same, but instead of using named arguments, you are using named properties (where syntax like [EnumDisplay(Description = null, Code = "C")] is only possible in attribute declarations).

Another way to think of it is that attribute declarations "borrowed" its syntax from method/constructor invocations, but attribute declarations are not in themselves method invocations, so they don't get all the same features as methods.

like image 100
Kirk Woll Avatar answered Oct 13 '22 01:10

Kirk Woll