Cela semblerait impliquer «non». Ce qui est malheureux.
[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);
}
}
Une classe peut-elle hériter des attributs d'une interface? Ou est-ce que j'aboie le mauvais arbre ici?
c#
attributes
Roger Lipscombe
la source
la source
Vous pouvez définir une méthode d'extension utile ...
Voici la méthode d'extension:
Mettre à jour:
Voici une version plus courte proposée par SimonD dans un commentaire:
la source
Apply
par le construitForEach
deMicrosoft.Practices.ObjectBuilder2
Un article de Brad Wilson à ce sujet: Attributs d'interface! = Attributs de classe
Pour résumer: les classes n'héritent pas des interfaces, elles les implémentent. Cela signifie que les attributs ne font pas automatiquement partie de l'implémentation.
Si vous avez besoin d'hériter d'attributs, utilisez une classe de base abstraite plutôt qu'une interface.
la source
Alors qu'une classe C # n'hérite pas des attributs de ses interfaces, il existe une alternative utile lors de la liaison de modèles dans ASP.NET MVC3.
Si vous déclarez que le modèle de la vue est l'interface plutôt que le type concret, alors la vue et le classeur de modèle appliqueront les attributs (par exemple,
[Required]
ou[DisplayName("Foo")]
depuis l'interface lors du rendu et de la validation du modèle:Puis dans la vue:
la source
C'est plus pour les personnes qui cherchent à extraire des attributs de propriétés qui peuvent exister sur une interface implémentée. Parce que ces attributs ne font pas partie de la classe, cela vous donnera accès à eux. note, j'ai une classe de conteneur simple qui vous donne accès à PropertyInfo - car c'est pour cela que j'en avais besoin. Hackez selon vos besoins. Cela a bien fonctionné pour moi.
la source
EDIT: cela couvre l'héritage des attributs des interfaces sur les membres (y compris les propriétés). Il y a des réponses simples ci-dessus pour les définitions de type. Je viens de publier ceci parce que j'ai trouvé que c'était une limitation irritante et que je voulais partager une solution :)
Les interfaces sont un héritage multiple et se comportent comme un héritage dans le système de types. Il n'y a pas une bonne raison pour ce genre de choses. La réflexion est un peu hokey. J'ai ajouté des commentaires pour expliquer le non-sens.
(Il s'agit de .NET 3.5 parce que c'est justement ce que le projet que je fais en ce moment utilise.)
Test Barebones NUnit
la source
Ajoutez une interface avec des propriétés qui ont des attributs / attributs personnalisés attachés aux mêmes propriétés que la classe. Nous pouvons extraire l'interface de la classe en utilisant la fonction de refactor de Visual studio. Demandez à une classe partielle d'implémenter cette interface.
Obtenez maintenant l'objet "Type" de l'objet de classe et obtenez des attributs personnalisés à partir des informations de propriété à l'aide de getProperties sur l'objet Type. Cela ne donnera pas les attributs personnalisés sur l'objet de classe car les propriétés de classe n'avaient pas les attributs personnalisés des propriétés d'interface attachés / hérités.
Appelez maintenant GetInterface (NameOfImplemetedInterfaceByclass) sur l'objet Type de la classe récupéré ci-dessus. Cela fournira l'objet "Type" de l'interface. nous devrions connaître le NOM de l'interface implémentée. À partir de l'objet Type, obtenez les informations de propriété et si la propriété de l'interface a des attributs personnalisés attachés, les informations de propriété fourniront une liste d'attributs personnalisés. La classe d'implémentation doit avoir fourni l'implémentation des propriétés de l'interface. Faites correspondre le nom de propriété spécifique de l'objet de classe dans la liste des informations de propriété de l'interface pour obtenir la liste des attributs personnalisés.
Cela fonctionnera.
la source
Bien que ma réponse soit tardive et spécifique à un cas particulier, j'aimerais ajouter quelques idées. Comme suggéré dans d'autres réponses, la réflexion ou d'autres méthodes le feraient.
Dans mon cas, une propriété (horodatage) était nécessaire dans tous les modèles pour répondre à certaines exigences (attribut de vérification de la concurrence) dans un projet de base du framework Entity. Nous pourrions soit ajouter [] au-dessus de toutes les propriétés de classe (l'ajout dans l'interface IModel quels modèles implémentés ne fonctionnaient pas). Mais j'ai gagné du temps grâce à l'API Fluent, ce qui est utile dans ces cas. Dans l'API fluide, je peux vérifier le nom de propriété spécifique dans tous les modèles et définir comme IsConcurrencyToken () en 1 ligne !!
De même, si vous avez besoin d'un attribut à ajouter au même nom de propriété dans des centaines de classes / modèles, nous pouvons utiliser des méthodes API fluides pour le résolveur d'attributs intégré ou personnalisé. Bien que l'API fluente EF (à la fois core et EF6) puisse utiliser la réflexion en arrière-plan, nous pouvons économiser des efforts :)
la source