Ich habe keine Attribute in meiner täglichen Arbeit vor, aber ich habe über sie gelesen. Auch ich habe ein paar Tests gemacht, um zu bestätigen, was ich hier sagen werde. Wenn ich irgendwo falsch liege - zögern Sie nicht, mir das zu sagen :)
Soweit ich weiß, sind Attribute nicht wie normale Klassen. Sie werden nicht instanziiert, wenn Sie ein Objekt erstellen, auf das sie angewendet werden, und nicht eine statische Instanz, nicht 1 pro Instanz des Objekts. Sie greifen auch nicht auf die Klasse zu, auf die sie angewendet werden.
Stattdessen verhalten sie sich wie Eigenschaften (Attribute?: P) der Klasse. Nicht wie die .NET Klasse Eigenschaften, eher wie in der "eine Eigenschaft von Glas ist Transparenz" Art der Eigenschaft.Sie können überprüfen, welche Attribute auf eine Klasse angewendet werden, und dann entsprechend reagieren. Sie sind im Wesentlichen Metadaten, die an die Klassendefinition angehängt werden, nicht die Objekte dieses Typs.
Sie können versuchen, die Liste der Attribute für eine Klasse, Methode, Eigenschaft, etc etc .. Wenn Sie die Liste dieser Attribute erhalten - das ist, wo sie instanziiert werden. Dann können Sie auf die Daten innerhalb dieser Attribute einwirken.
z. In den Linq-Tabellen haben Eigenschaften Attribute, die definieren, auf welche Tabelle/Spalte sie sich beziehen. Diese Klassen verwenden diese Attribute jedoch nicht. Stattdessen überprüft der DataContext die Attribute dieser Objekte, wenn linq-Ausdrucksbäume in SQL-Code konvertiert werden.
Jetzt für einige echte Beispiele .. Ich habe diese in LinqPad ausgeführt, also mach dir keine Sorgen über die seltsame Dump() -Methode. Ich habe es mit Console.WriteLine ersetzt den Code leichter zu machen für die Menschen zu verstehen, die darüber nicht wissen :)
void Main()
{
Console.WriteLine("before class constructor");
var test = new TestClass();
Console.WriteLine("after class constructor");
var attrs = Attribute.GetCustomAttributes(test.GetType()).Dump();
foreach(var attr in attrs)
if (attr is TestClassAttribute)
Console.WriteLine(attr.ToString());
}
public class TestClassAttribute : Attribute
{
public TestClassAttribute()
{
DefaultDescription = "hello";
Console.WriteLine("I am here. I'm the attribute constructor!");
}
public String CustomDescription {get;set;}
public String DefaultDescription{get;set;}
public override String ToString()
{
return String.Format("Custom: {0}; Default: {1}", CustomDescription, DefaultDescription);
}
}
[Serializable]
[TestClass(CustomDescription="custm")]
public class TestClass
{
public int Foo {get;set;}
}
Die Konsole Ergebnis dieser Methode ist:
before class constructor
after class constructor
I am here. I'm the attribute constructor!
Custom: custm; Default: hello
und die Attribute.GetCustomAttributes(test.GetType())
gibt dieses Array: (die Tabelle zeigt alle verfügbaren Spalten für alle Einträge .. Also nein, das Attribut Serializable haben diese Eigenschaften nicht :))
jede mor Got Die Fragen? Fragen sind willkommen!
UPD: Ich habe gesehen, dass Sie eine Frage stellen: warum sie verwenden? Als Beispiel erzähle ich Ihnen über die XML-RPC.NET-Bibliothek. Sie erstellen Ihre XML-RPC-Serviceklasse mit Methoden, die die xml-rpc-Methoden darstellen. Die Hauptsache ist gerade: In XmlRpc können die Methodennamen einige Sonderzeichen haben, wie Punkte. Sie können also eine flexlabs.ProcessTask() xml rpc-Methode verwenden.
Sie würden diese Klasse wie folgt definieren:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
Das bin ich die Methode in der Art und Weise zu nennen erlaubt es mir gefällt, während immer noch die Öffentlichkeit Namen, wie es sein muss.
+1 Jeder für hilfreiche Antworten. Jetzt verstehe ich klar, dass Attribute selbst kein Verhalten haben und das Verhalten der Klasse, auf die sie angewendet werden, nicht ändern. Sie sind einfach zusätzliche Metadaten, die an eine Klasse angeheftet sind. Was ich als "Verhalten" empfand, war eigentlich nicht der Code der Attributklasse, sondern nur anderer Code wie die Serialize-Methode, die Metadaten interpretierte und bedingte Aktionen ausführte (z. B. eine Serialize-Methode mit Blick auf das Serializable-Attribut). – AaronLS
Sehen Sie für gutes Beispiel von, wenn Attributkonstruktoren laufen: http://stackoverflow.com/a/1168590/84206 – AaronLS