2009-06-10 9 views
9

Ich verstehe nicht wirklich Attribute. Ich habe alle Arten von Büchern & Beiträge auf ihnen gelesen, aber ich verstehe es einfach nicht.Was ist der beste Weg, um benutzerdefinierte Attribute in dotnet/.NET zu implementieren?

Da ich sie nicht verstehe, verstehe ich auch nicht, wie man sie effektiv benutzt.

1) Können Sie mir eine gute Definition geben, was ein Attribut ist &, wofür es verwendet wird?

2) Können Sie mir ein gutes Codebeispiel in C# geben, wie ein benutzerdefiniertes Attribut erstellt und verwendet wird?

Antwort

9

Angenommen, Sie haben eine Klasse mit einer Reihe von Eigenschaften, die Sie durch Reflexion durchlaufen werden. Alle Strings müssen möglicherweise validiert werden, um zu überprüfen, dass sie nicht länger als ein bestimmter Betrag sind.

Sie könnten dann ein textLength-Attribut mit einem standardmäßigen Integer-Konstruktor und einer Integer-Eigenschaft/field erstellen. Sie könnten dann Ihr Attribut für jede String-Eigenschaft in Ihrer Klasse lesen und die Länge des Eigenschaftswerts mit der im Attribut angegebenen Zahl vergleichen.

Code:

public class TextLengthAttribute : Attribute 
{ 
    private int length; 
    public int Length { get { retrun length; } set { length = value; } } 

    public TextLengthAttribute(int num) { this.length = num ; } 
} 

public class MyClass 
{ 

    [TextLength(10)] 
    public string Property1; 
    [TextLength(20)] 
    public string Property2; 
} 

public class ClassReader 
{ 
    public static void Main() 
    { 
      MyClass example = MyClass.GetTestData(); 

      PropertyInfo[] props = typeof(MyClass).GetProperties(); 
      foreach (PropertyInfo prop in props) 
      { 
       if (prop.ValueType == typeof(String) 
       { 
        TextLengthAttribute[] atts = 
         (TextLengthAttribute)[]prop.GetCustomAttributes(
          typeof(TextLengthAttribute), false); 
        if (prop.GetValue(example, null).ToString().Length > 
         atts[0].Length) 
         throw new Exception(prop.name + " was too long"); 
       } 
      } 
    } 
} 

Hinweis: ungetestet

2

Haben Sie viel bei z. log4PostSharp. Sie verwenden Attribute, um AOP-Verhalten einzuführen.

Das ist ein Attribut ich einmal verwendet, Eigenschaften eine Einheit zu geben (wie Sekunden, Meter, ...)

[AttributeUsage(AttributeTargets.Property)] 
public sealed class UnitAttribute : Attribute 
{ 
    public UnitAttribute(Unit unit) 
    { 
    Unit = unit; 
    } 

    public Unit Unit { get; private set; } 
} 

Es auf Eigenschaften verwendet wurde, wie folgt aus:

[Unit(Unit.Meter)] 
public float Distance { get; set; } 

Sie kann später das Attribut abrufen, um es auf der GUI anzuzeigen.

11

Ich könnte Ihnen ein Beispiel geben, aber es wäre im Vergleich zu diesem feinen Artikel blass:

Defining and Using Custom Attribute Classes in C#

Der Komplex, Komponente Stil Entwicklung, dass Unternehmen von Entwicklern moderner Software erwarten heraus erfordert größere Design-Flexibilität als die Design-Methoden der Vergangenheit. Microsoft .NET Framework macht umfangreiche Verwendung von Attributen, um zusätzliche Funktionalität durch was ist bekannt als "deklarative" Programmierung. Attribute erhöhen die Flexibilität in Software-Systeme, weil sie losen Kopplung der Funktionalität fördern. Da Sie Ihre eigenen benutzerdefinierten Attributklassen erstellen und dann auf sie handeln können, können Sie die lose Kopplungsstärke von Attributen für Ihre eigenen eigenen Zwecke nutzen.

2

Ein Attribut verwendet wird, Meta-Daten über jedes Mitglied (Felder, Klasse usw.) zur Verfügung zu stellen.

Sie können sie erstellen, indem Sie von Attribute erben und sie mithilfe der Methode Attribute.GetCustomAttribute konsumieren.

Ein Beispiel für ein Standardattribut ist die PrincipalPermissionAttribute, die authentifizierten Benutzern nur den Zugriff auf bestimmte Ressourcen ermöglicht.Zum Beispiel:

[PrincipalPermission (SecurityAction.Demand, Role="Supervisor")] 
public class DoTheThingPage : Page 
{ 
    //// 
} 

In diesem Beispiel haben wir eine ASP.NET-Seite, die von einem authentifizierten Benutzer kann nur angezeigt werden, die auf den "Supervisor-Rolle gehört.

Beachten Sie auch, dass der ‚Attribut‘ Teil des Klassennamen nicht verwendet wurde (Dieses Attribut automatisch durch das Sicherheitsuntersystem in ASP.NET gelesen wird), ist es eine Konvention in .NET.

3

Wir haben die Anforderung, Enum-Werte in einer Dropdown-Liste in einer bestimmten Sortierreihenfolge anzuzeigen. Wir haben benutzerdefinierte Attribute implementiert.

[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false)] 
public class EnumSortAttribute : Attribute 
{ 
    public int SortOrder; 
    public bool SortByDescription; 
} 

[EnumSort(SortByDescription=true)] 
public enum EnumSortByDescription 
{ 
    [Description("enO")] 
    One = 1, 
    [Description("2")] 
    Two = 2, 
    Three = 3, 
    [Description("rouF")] 
    Four = 4 
} 

public enum EnumCustomSortOrder 
{ 
    [EnumSort(SortOrder = 3)] 
    One = 1, 
    [EnumSort(SortOrder = 1)] 
    Two = 2, 
    [EnumSort(SortOrder = 2)] 
    Three = 3 
} 
1

Attribut ist nur ein Weg zusätzliche Informationen (Metadaten) zu der Klasse, Struktur oder ein Mitglied hinzuzufügen. Diese Metadaten könnten von anderem Code abgerufen werden, um einige Entscheidungen zu treffen.

Einfachstes Beispiel ist SerializableAttribute von der .NET. Es zeigt an, dass die Klasse später von einem BinaryFormatter serialisiert werden konnte.

Hier ein weiteres Beispiel - wir einige Klassen in unserem Code mit ImmutableAttribute markieren könnten, um anzuzeigen, dass sie keine änderbaren Felder und OK sind für Multi-Threaded-Operationen:

[Immutable] 
public sealed class ProcessingMessage 
{ 
    //... some code that should be thread-safe 

} 

Dann wir könnte einen Komponententest erstellen, der alle Klassen mit dem Attribut findet und dafür sorgt, dass they are immutable indeed:

[Test] 
public void Immutable_Types_Should_Be_Immutable() 
{ 
    var decorated = GlobalSetup.Types 
    .Where(t => t.Has<ImmutableAttribute>()); 

    foreach (var type in decorated) 
    { 
    var count = type.GetAllFields().Count(f => !f.IsInitOnly && !f.IsStatic); 
    Assert.AreEqual(0, count, "Type {0} should be immutable", type); 
    } 
} 
Verwandte Themen