Why would one want to use AttributeUsage AllowMultiple when creating attributes?

According to a book I'm reading, the AllowMultiple public property of AttributeUsage specifies:

...whether the target can have multiple instances of the attribute applied to it.

Why would I want/not want to use this?

Answers


Attributes are meta-data. Typically, you'll want to decorate a member or type with an Attribute in order to track some information about it.

For example, the DescriptionAttribute is used by the PropertyGrid to label a description of a property:

[Description("This is my property")]
public int MyProperty { get; set; }

Most of the time, having more than one description would not make sense.

However, it is possible that a specific attribute makes sense to use more than once. In that case, you'd want to set the Attribute to allow multiple instances of itself tagged to the same attribute.

(Not that I'd do this, but...) Say you made a custom attribute to track major changes to a class. You might want to list this for every major change:

[Changes(Version=1.1, Change="Added Foo Feature")]
[Changes(Version=2.0, Change="Added Bar Feature")]
public class MyClass
{
    // ...

This example might be a little contrived but hopefully it gets the point across.

[Convertable(typeof(Int32)), Convertable(typeof(Double))]
public class Test
{

}

This depends what the attributes are.

For example, you could make an attribute that marks a class as depending on something, and you could allow multiple dependencies.

For a concrete example, look at SuppressMessage, which suppresses a code analysis warning. A member can have multiple warnings that you might want to suppress.

Another example is WebResource; an assembly can contain multiple resources.


No contrived example here, I used it in real production code. I wrote some code to parse a file containing pairs of data like (code=value). I put a custom attribute on a function to indicate it should be called for a given code.

[CanParseCode("G1")]
[CanParseCode("G2")]
private void ParseGXCodes(string code, string value)
{
   ...
}

This particular format is a somewhat old and domain specific with hundreds of different codes. My goal was to write a framework to make it easier to write file processors that could extract only the codes it needs and ignore the rest. Allowing the same attribute multiple times made it easy to express the intent of the code by simply declaring attributes on the function(s) that process each code.


Real World Application of Attribute AllowMultiple=true usefulness

[ManagesType(typeof(SPEC_SEC_OC), true)]
[ManagesType(typeof(SPEC_SEC_04_OC), true)]
public class LibSpecSelectionView : CustomView
{
    public LibSpecSelectionView(SPEC_SEC_OC)
    {}
    public LibSpecSelectionView(SPEC_SEC_O4_OC)
    {}
    ....
}

public static class ViewManager
{
   ...  static Dictionary of views built via reflection
   public void LaunchView(this CollectionBaseClass cbc)
   {
       ... Find class registered to handle cbc type in dictionary and call ctor
   }
}

SPEC_SEC_OC myOC = DataClient.Instance.GetSPEC_SEC_OC();
myOC.LaunchView()

I flipped AllowMultiple=true earlier today to allow for the ManagesType attribute to be used more than once. We have several hundred Custom Collection Classes. Most of these custom collections have a view that inherits from CustomView designed to handle creation of a UI view for a specific type of custom collection and presenting it to the user. The ManagesType attribute is used via reflection to build a dictionary of EVERY View in our app that inherits from CustomView to "register" what object type it was designed to handle. The LibSpecSelectionView "broke that pattern" by displaying two different collections at the same time (creates two tabs and shows one custom collection in one tab and the other in the second tab) So the same view is capable of handling two different custom collections. The dictionary of which views are capable of handling which collection types is then leveraged through an extension method to allow any of our custom collections to launch the registered view (or a default one if there is not a "registered" view) through a one line call to the view manager.


Need Your Help

Round .NET DateTime milliseconds, so it can fit SQL Server milliseconds

c# sql-server sql-server-2008 datetime

I want to convert the datetime value to the value that I will get from SQL Server 2008.