This would appear to imply "no". Which is unfortunate.
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class,
AllowMultiple = true, Inherited = true)]
public class CustomDescriptionAttribute : Attribute
{
public string Description { get; private set; }
public CustomDescriptionAttribute(string description)
{
Description = description;
}
}
[CustomDescription("IProjectController")]
public interface IProjectController
{
void Create(string projectName);
}
internal class ProjectController : IProjectController
{
public void Create(string projectName)
{
}
}
[TestFixture]
public class CustomDescriptionAttributeTests
{
[Test]
public void ProjectController_ShouldHaveCustomDescriptionAttribute()
{
Type type = typeof(ProjectController);
object[] attributes = type.GetCustomAttributes(
typeof(CustomDescriptionAttribute),
true);
// NUnit.Framework.AssertionException: Expected: 1 But was: 0
Assert.AreEqual(1, attributes.Length);
}
}
Can a class inherit attributes from an interface? Or am I barking up the wrong tree here?
No. Whenever implementing an interface or overriding members in a derived class, you need to re-declare the attributes.
If you only care about ComponentModel (not direct reflection), there is a way (
[AttributeProvider]
) of suggesting attributes from an existing type (to avoid duplication), but it is only valid for property and indexer usage.As an example:
outputs:
You can define a useful extension method ...
Here is the extension method:
Update:
Here is a shorter version as proposed by SimonD in a comment:
An article by Brad Wilson about this: Interface Attributes != Class Attributes
To summarise: classes don't inherit from interfaces, they implement them. This means that the attributes are not automatically part of the implementation.
If you need to inherit attributes, use an abstract base class, rather than an interface.
While a C# class does not inherit attributes from its interfaces, there is a useful alternative when binding models in ASP.NET MVC3.
If you declare the view's model to be the interface rather than the concrete type, then the view and the model binder will apply the attributes (e.g.,
[Required]
or[DisplayName("Foo")]
from the interface when rendering and validating the model:Then in the view:
EDIT: this covers inheriting attributes from interfaces on members (incl. properties). There are simple answers above for type definitions. I just posted this because I found it to be an irritating limitation and wanted to share a solution :)
Interfaces are multiple inheritance and behave as inheritance in the type system. There isn't a good reason for this kind of stuff. Reflection is a bit hokey. I've added comments to explain the nonsense.
(This is .NET 3.5 because this it just happens to be what the project I'm doing at the moment is using.)
Barebones NUnit test
This is more for people looking to extract attributes from properties that may exist on an implemented interface. Because those attributes are not part of the class, this will give you access to them. note, I have a simple container class that gives you access to the PropertyInfo - as that is what I needed it for. Hack up as you need. This worked well for me.