Given the following, I would not expect the compiler to allow multiple attributes that are derived from the base attribute, given that is set to AllowMultiple=false. In fact it compiles without a problem - what am I missing here?
using System;
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=true)]
abstract class BaseAttribute : Attribute { }
sealed class DerivedAttributeA : BaseAttribute { }
sealed class DerivedAttributeB : BaseAttribute { }
class Sample1
{
[DerivedAttributeA()]
[DerivedAttributeB()]
public string PropertyA{ get; set; } // allowed, concrete classes differ
[DerivedAttributeA()]
[DerivedAttributeA()]
public string PropertyB { get; set; } // not allowed, concrete classes the same, honours AllowMultiple=false on BaseAttribute
}
The problem is simply that the AllowMultiple
check only compares attributes of the same actual type (i.e. the concrete type instantiated) - and is perhaps best used with sealed
attributes for this reason.
It will, for example, enforce the following (as an illegal duplicate), inheriting this from BaseAttribute
:
[DerivedAttributeB()]
[DerivedAttributeB()]
public string Name { get; set; }
In short, I don't think you can do what you want here... (enforce no more than one instance including subclasses of BaseAttribute
per property).
A similar example of this problem would be:
[Description("abc")]
[I18NDescriptionAttribute("abc")]
public string Name { get; set; }
class I18NDescriptionAttribute : DescriptionAttribute {
public I18NDescriptionAttribute(string resxKey) : base(resxKey) { }
}
The intent above is to provide a [Description]
from resx at runtime (fully supported by ComponentModel
etc) - but it can't stop you also adding a [Description]
.