Dies scheint "nein" zu bedeuten. Welches ist unglücklich.
[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);
}
}
Kann eine Klasse Attribute von einer Schnittstelle erben? Oder belle ich hier den falschen Baum an?
c#
attributes
Roger Lipscombe
quelle
quelle
Sie können eine nützliche Erweiterungsmethode definieren ...
Hier ist die Erweiterungsmethode:
Aktualisieren:
Hier ist eine kürzere Version, wie von SimonD in einem Kommentar vorgeschlagen:
quelle
Apply
den eingebautenForEach
vonMicrosoft.Practices.ObjectBuilder2
Ein Artikel von Brad Wilson dazu: Interface Attributes! = Class Attributes
Zusammenfassend: Klassen erben nicht von Schnittstellen, sondern implementieren sie. Dies bedeutet, dass die Attribute nicht automatisch Teil der Implementierung sind.
Wenn Sie Attribute erben müssen, verwenden Sie eine abstrakte Basisklasse anstelle einer Schnittstelle.
quelle
Während eine C # -Klasse keine Attribute von ihren Schnittstellen erbt, gibt es eine nützliche Alternative beim Binden von Modellen in ASP.NET MVC3.
Wenn Sie das Modell der Ansicht als Schnittstelle und nicht als konkreten Typ deklarieren, wenden die Ansicht und der Modellordner die Attribute an (z. B.
[Required]
oder[DisplayName("Foo")]
über die Schnittstelle beim Rendern und Validieren des Modells:Dann in der Ansicht:
quelle
Dies ist eher für Personen gedacht, die Attribute aus Eigenschaften extrahieren möchten, die möglicherweise auf einer implementierten Schnittstelle vorhanden sind. Da diese Attribute nicht Teil der Klasse sind, erhalten Sie Zugriff darauf. Hinweis: Ich habe eine einfache Containerklasse, mit der Sie auf die PropertyInfo zugreifen können. Dafür habe ich sie benötigt. Hacke nach Bedarf. Das hat bei mir gut funktioniert.
quelle
BEARBEITEN: Dies umfasst das Erben von Attributen von Schnittstellen auf Mitgliedern (inkl. Eigenschaften). Es gibt oben einfache Antworten für Typdefinitionen. Ich habe dies gerade gepostet, weil ich es als irritierende Einschränkung empfand und eine Lösung teilen wollte :)
Schnittstellen sind Mehrfachvererbungen und verhalten sich im Typsystem wie Vererbungen. Es gibt keinen guten Grund für solche Sachen. Reflexion ist ein bisschen hokey. Ich habe Kommentare hinzugefügt, um den Unsinn zu erklären.
(Dies ist .NET 3.5, da dies zufällig das ist, was das Projekt, das ich gerade mache, verwendet.)
Barebones NUnit-Test
quelle
Fügen Sie eine Schnittstelle mit Eigenschaften hinzu, deren Attribute / benutzerdefinierte Attribute denselben Eigenschaften wie die Klasse zugeordnet sind. Wir können die Schnittstelle der Klasse mithilfe der Visual Studio-Refactor-Funktion extrahieren. Lassen Sie diese Schnittstelle von einer Teilklasse implementieren.
Holen Sie sich jetzt das "Type" -Objekt des Klassenobjekts und rufen Sie mithilfe von getProperties on Type-Objekt benutzerdefinierte Attribute aus den Eigenschaftsinformationen ab. Dadurch werden die benutzerdefinierten Attribute für das Klassenobjekt nicht angegeben, da an die Klasseneigenschaften die benutzerdefinierten Attribute der Schnittstelleneigenschaften nicht angehängt / geerbt wurden.
Rufen Sie nun GetInterface (NameOfImplemetedInterfaceByclass) für das oben abgerufene Type-Objekt der Klasse auf. Dadurch wird das Objekt "Typ" der Schnittstelle bereitgestellt. Wir sollten den NAMEN der implementierten Schnittstelle kennen. Rufen Sie vom Typ-Objekt Eigenschaftsinformationen ab. Wenn an die Eigenschaft der Schnittstelle benutzerdefinierte Attribute angehängt sind, stellen die Eigenschaftsinformationen eine benutzerdefinierte Attributliste bereit. Die implementierende Klasse muss die Implementierung der Eigenschaften der Schnittstelle bereitgestellt haben. Passen Sie den spezifischen Eigenschaftsnamen des Klassenobjekts an die Liste der Eigenschaftsinformationen der Schnittstelle an, um die Liste der benutzerdefinierten Attribute abzurufen.
Das wird funktionieren.
quelle
Obwohl meine Antwort zu spät und spezifisch für einen bestimmten Fall ist, möchte ich einige Ideen hinzufügen. Wie in anderen Antworten vorgeschlagen, würde Reflection oder andere Methoden dies tun.
In meinem Fall wurde in allen Modellen eine Eigenschaft (Zeitstempel) benötigt, um bestimmte Anforderungen (Attribut zur Überprüfung der Parallelität) in einem Entity Framework-Kernprojekt zu erfüllen. Wir könnten entweder [] vor allem Klasseneigenschaften hinzufügen (in der IModel-Schnittstelle hinzufügen, welche Modelle implementiert wurden, hat nicht funktioniert). Durch die Fluent API habe ich jedoch Zeit gespart, was in diesen Fällen hilfreich ist. In der fließenden API kann ich in allen Modellen nach bestimmten Eigenschaftsnamen suchen und in einer Zeile IsConcurrencyToken () festlegen !!
Wenn Sie in Hunderten von Klassen / Modellen ein Attribut zum selben Eigenschaftsnamen hinzufügen müssen, können wir auch fließende API-Methoden für den eingebauten oder benutzerdefinierten Attribut-Resolver verwenden. Obwohl die fließende API von EF (sowohl Core als auch EF6) möglicherweise Reflexion hinter den Kulissen verwendet, können wir Mühe sparen :)
quelle