Peut une classe C# héritent des attributs à partir de son interface?
Cela semblerait impliquer "non". Ce qui est regrettable.
[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);
}
}
Peut une classe hérite des attributs à partir d'une interface? Ou suis-je aboiements le mauvais arbre ici?
Vous devez vous connecter pour publier un commentaire.
Pas. Chaque fois que la mise en œuvre d'une interface ou d'écraser des membres dans une classe dérivée, vous avez besoin de re-déclarer les attributs.
Si vous ne se soucient ComponentModel (pas de reflet direct), il existe un moyen (
[AttributeProvider]
) de proposer des attributs à partir d'un type existant (pour éviter les doublons), mais c'est seulement valide pour la propriété et l'utilisation de l'indexeur.Comme un exemple:
sorties:
Vous pouvez définir une extension utile méthode ...
Ici est la méthode d'extension:
Mise à jour:
Ici est une version plus courte proposée par SimonD dans un commentaire:
Apply
avec le construit enForEach
deMicrosoft.Practices.ObjectBuilder2
Un article de Brad Wilson, à ce sujet: Des Attributs De L'Interface != Les Attributs De Classe
Pour résumer: les classes ne pas hériter d'interfaces, ils mettent en œuvre. Cela signifie que les attributs ne sont pas automatiquement partie de la mise en œuvre.
Si vous avez besoin d'hériter des attributs, utilisez une classe de base abstraite, plutôt que d'une interface.
Tandis qu'une classe C# ne pas hériter des attributs de ses interfaces, il est une alternative utile lors de modèles de liaison dans ASP.NET MVC3.
Si vous déclarez la vue du modèle à l'interface plutôt que le type de béton, puis la vue et le modèle de classeur appliquer les attributs (par exemple,
[Required]
ou[DisplayName("Foo")]
à partir de l'interface lors du rendu et de la validation du modèle:Puis dans la vue:
C'est plus pour les gens 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, ce qui vous donnera accès à eux. remarque, j'ai un simple conteneur de classe qui vous donne accès à la PropertyInfo - que c'est ce que j'en avais besoin pour. Pirater que vous en avez besoin. Cela a bien fonctionné pour moi.
EDIT: ce couvre hériter des attributs à partir des interfaces sur les membres (incl. les propriétés). Il y a des réponses simples ci-dessus pour les définitions de type. J'ai juste posté ça parce que je trouve qu'il est un irritant limitation et je voulais partager une solution 🙂
Interfaces sont l'héritage multiple et de se comporter comme héritage dans le système de type. Il n'y a pas une bonne raison pour ce genre de trucs. La réflexion est un peu à l'eau de rose. J'ai ajouté des commentaires pour expliquer le non-sens.
(C'est .NET 3.5, car ce qu'il se trouve être exactement ce que le projet que je suis en train de faire en ce moment est de l'aide.)
Barebones de test NUnit
Ajouter de l'interface avec les propriétés qui ont des attributs/attributs personnalisés attaché à les mêmes propriétés que la classe ont. Nous pouvons extraire l'interface de la classe à l'aide de Visual studio refactoriser fonctionnalité.
Avoir une classe partielle à implémenter cette interface.
Maintenant Obtenir "Type" d'objet de l'objet de classe et d'obtenir les attributs personnalisés à partir de la propriété de l'info à l'aide de getProperties sur le Type d'objet.
Ce ne sera pas lui donner les attributs personnalisés sur la classe de l'objet que les propriétés de la classe n'en avaient pas les propriétés de l'interface' attributs personnalisés attaché/a hérité.
Maintenant appel GetInterface(NameOfImplemetedInterfaceByclass) sur la classe de Type de l'objet (extrait ci-dessus. Ce sera
fournir de l'interface de Type "objet". nous devrions savoir la mise en œuvre de l'interface de NOM. De Type objet d'obtenir de l'information sur les biens et si l'interface est bien a tous les attributs attachés alors propriété de l'information
attribut personnalisé de la liste. La mise en œuvre de la classe doit avoir fourni de la mise en œuvre des propriétés de l'interface.
Correspond à la classe de l'objet spécifique de la propriété du nom dans la liste de l'interface de la propriété de l'information pour obtenir les attributs personnalisés liste.
Cela fonctionne.
Bien que ma réponse est tardive et spécifiques à certains cas, je voudrais ajouter quelques idées.
Comme suggéré dans d'autres réponses, de Réflexion ou d'autres méthodes qui l'aurait fait.
Dans mon cas une propriété (timestamp) était nécessaire dans tous les modèles afin de répondre à certains besoins (contrôle d'accès concurrentiel attribut) dans une Entité cadre du projet core.
Nous pourrions ajouter [] au-dessus de toutes les propriétés de la classe (et en ajoutant IModel interface de modèles mis en œuvre, n'a pas fonctionné). Mais j'ai sauvé le temps à travers les API Fluent qui est utile dans ces cas. Dans l'API, je peux vérifiez que le nom de la propriété dans tous les modèles et les définir comme IsConcurrencyToken() in 1 line !!
De même, si vous avez besoin de n'importe quel attribut d'être ajouté à même nom de propriété dans 100 de classes et/ou des modèles, nous pouvons utiliser l'api fluent méthodes pour intégré ou un attribut personnalisé de résolution.
Si EF (à la fois le noyau et EF6) api fluent peut utiliser la réflexion derrière les scènes, nous pouvons économiser de l'effort 🙂