Nützlichste Attribute [geschlossen]

784

Ich weiß, dass Attribute äußerst nützlich sind. Es gibt einige vordefinierte, mit [Browsable(false)]denen Sie Eigenschaften auf der Registerkarte Eigenschaften ausblenden können. Hier ist eine gute Frage zur Erklärung von Attributen: Was sind Attribute in .NET?

Welche vordefinierten Attribute (und deren Namespace) verwenden Sie tatsächlich in Ihren Projekten?

wusher
quelle
27
Was für eine Frage? Die gesamte Seite ist überfüllt mit wunderschönen Antworten mit wunderbaren Erklärungen. Während ich dies durchlese, habe ich die Erfahrung gemacht, viele Experten über ihre Sichtweise zu befragen. +100 für die Frage.
Muthu Ganapathy Nathan
Ich stimme zu, Fragen wie diese sind einige der wertvollsten - macht SO weniger nützlich, dass sie geschlossen werden.
David Thielen

Antworten:

669

[DebuggerDisplay]Dies kann sehr hilfreich sein, um die angepasste Ausgabe eines Typs schnell anzuzeigen, wenn Sie beim Debuggen mit der Maus über die Instanz des Typs fahren. Beispiel:

[DebuggerDisplay("FirstName={FirstName}, LastName={LastName}")]
class Customer
{
    public string FirstName;
    public string LastName;
}

So sollte es im Debugger aussehen:

Alt-Text

Erwähnenswert ist auch, dass ein [WebMethod]Attribut mit CacheDurationEigenschaftssatz eine unnötige Ausführung der Webdienstmethode vermeiden kann.

Vivek
quelle
62
Wow, das ist wirklich gut zu wissen. Normalerweise habe ich das Gleiche erreicht, indem ich ToString überschrieben habe, aber das ist besser.
Brian
17
Seien Sie vorsichtig damit, es beißt viel mehr Teile aus Ihrer CPU als ToString.
Nikola Radosavljević
1
Sie können dies auch verwenden, um das Ergebnis von Methoden anzuzeigen. Dies kann zu einer ziemlich verwirrenden Debugging-Erfahrung führen, wenn die Methode (oder Property-Get) Nebenwirkungen hat.
Øyvind Skaar
4
@ NikolaRadosavljević würde es nur CPU-Leistung während des Debuggens verbrauchen
Nickolay Kondratyev
2
@Nickolay Kondratyev: Ich kenne nicht alle Vor- und Nachteile, aber Sie können einen Blick auf die folgenden Best Practices für Webdienste werfen, die Sie zu einigen Schlussfolgerungen führen können: blogs.msdn.com/b/jaredpar/archive/2011/03/ 18 /…
Nikola Radosavljević
273

System.Obsoleteist meiner Meinung nach eines der nützlichsten Attribute im Framework. Die Möglichkeit, eine Warnung über Code auszulösen, der nicht mehr verwendet werden sollte, ist sehr nützlich. Ich mag es, Entwicklern zu sagen, dass etwas nicht mehr verwendet werden sollte, und zu erklären, warum und auf die bessere / neue Art hinzuweisen, etwas zu tun.

Das Conditional attributeist auch ziemlich praktisch für die Debug-Verwendung. Sie können Ihrem Code Methoden für Debug-Zwecke hinzufügen, die beim Erstellen Ihrer Release-Lösung nicht kompiliert werden.

Dann gibt es viele Attribute, die für Web Controls spezifisch sind und die ich nützlich finde, aber diese sind spezifischer und haben keine Verwendung außerhalb der Entwicklung von Server Controls, die ich gefunden habe.

Dan Herbert
quelle
50
Sie können "true" als einen der Parameter an System.Obsolete übergeben, wodurch die Warnung zu einem Fehler wird und der Build unterbrochen wird. Dies sollte natürlich geschehen, sobald Sie alle Warnungen bereinigt haben. :)
Adrian Clark
14
Wäre es nicht besser, die Methode zu löschen, wenn Sie alle Warnungen bereinigt haben?
Pedro
10
@Pedro: Manchmal kann man aus Gründen der Abwärtskompatibilität nicht. Wenn es privat und unbenutzt ist, löschen Sie es.
Fantius
3
@plinth Das Auslösen einer Ausnahme wäre aus vielen Gründen eine schlechte Idee. # 1 ist, dass der Hauptgrund für die Verwendung von Obsolete () darin besteht, dass Sie kompilierten Code in einer Übergangsphase weiterarbeiten können. Wenn Sie niemandem erlauben, die Methode aufzurufen, löschen Sie sie einfach.
Dan Herbert
17
@plinth Damit soll verhindert werden, dass neuer Code die Methode verwendet. Alter Code bleibt binärkompatibel, wenn eine Methode als veraltet markiert ist, funktioniert jedoch nicht mehr, wenn Sie eine Ausnahme auslösen. Wenn jemand Reflexion verwendet, um die "veraltete" Flagge zu umgehen, dann haben Sie schlimmere Probleme ...
Dan Herbert
204

[Flags]ist ziemlich praktisch. Syntaktischer Zucker zwar, aber immer noch ziemlich schön.

[Flags] 
enum SandwichStuff
{
   Cheese = 1,
   Pickles = 2,
   Chips = 4,
   Ham = 8,
   Eggs = 16,
   PeanutButter = 32,
   Jam = 64
};

public Sandwich MakeSandwich(SandwichStuff stuff)
{
   Console.WriteLine(stuff.ToString());
   // ...
}

// ...

MakeSandwich(SandwichStuff.Cheese 
   | SandwichStuff.Ham 
   | SandwichStuff.PeanutButter);
// produces console output: "Cheese, Ham, PeanutButter"

Leppie weist darauf hin , etwas , das ich nicht erkannt hatte, und die eher dämpft meine Begeisterung für dieses Attribut: es funktioniert nicht anweisen , den Compiler Bit - Kombinationen als gültige Werte für Aufzählungs Variablen zu ermöglichen, der Compiler dies unabhängig für Aufzählungen ermöglicht. Mein C ++ - Hintergrund zeigt sich durch ... seufz

Shog9
quelle
Was genau macht das Flags-Attribut?
Andrei Rînea
13
Ich hoffe, euch ist klar, dass das Flags-Attribut alles nervt. Es wird mit Ausnahme des TypeConverter überhaupt nicht benötigt / verwendet.
Leppie
3
@leppie: ToString () auch. Aber ... wow. Aus irgendeinem Grund hatte ich erwartet, dass das Verhalten von Aufzählungen ohne das Attribut mit C ++ identisch ist: or'd-Werte erzeugen eine Ganzzahl (kann nicht unverändert an die Methode übergeben werden, die Enum-Parameter erwartet). Ich sehe jetzt, dass das nicht der Fall ist. Schwach ... ok, .NET-Enums saugen.
Shog9
2
[Flags] hilft den Funktionen Debugger und .ToString () nur zu erkennen, dass ein Wert möglicherweise eine Kombination mehrerer Deklarationen in der Aufzählung ist. Ich bin mir nicht sicher, ob Intellisense Ihnen dabei helfen könnte, die Aufzählung auch effektiver zu nutzen.
Kenzi
31
[Flags]hat eine größere Verwendung als nur syntaktischer Zucker. Während der Verwendung von Webdiensten funktioniert die Serialisierung / De-Serialisierung nicht, wenn ein Wert wie übergeben SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jamwird. Ohne das [Flags]Attribut weiß der Deserializer nicht, dass der Wert eine Kombination von Flags sein kann. Ich habe das auf die harte Tour gelernt, nachdem ich ungefähr zwei Tage lang darüber nachgedacht hatte, warum meine WCF nicht funktionierte.
Anchit
177

Ich mag [DebuggerStepThrough]von System.Diagnostics .

Dies ist sehr praktisch, um zu vermeiden, dass Sie in diese einzeiligen Do-Nothing-Methoden oder -Eigenschaften eintreten (wenn Sie gezwungen sind, in einem frühen .Net ohne automatische Eigenschaften zu arbeiten). Wenn Sie das Attribut auf eine kurze Methode oder den Getter oder Setter einer Eigenschaft setzen, fliegen Sie direkt vorbei, selbst wenn Sie im Debugger auf "step into" klicken.

Blair Conrad
quelle
5
So oft wünschte ich, ich wüsste etwas über diese Immobilie
wusher
1
Nur schade, dass es mit Verschlüssen kaputt ist - siehe gregbeech.com/blogs/tech/archive/2008/10/17/… für weitere Informationen.
Greg Beech
3
Auch nützlich für jeden WM_Paint Code, von dem Sie wissen, dass er funktioniert :)
Pondidum
@ GregBeech Diese URL gibt einen .NET-Fehler zurück. Nobel! :)
smdrager
@smdrager - Muss ein vorübergehendes Problem gewesen sein, scheint heute für mich zu funktionieren.
Greg Beech
135

Hier ist eine Liste aller .NET-Attribute . Es gibt mehrere hundert.

Ich weiß von niemand anderem, aber ich habe ernsthaftes RTFM zu tun!

wprl
quelle
33
Gepostete Liste ist für .net 1.1 Hier ist die Liste für 3.5 msdn.microsoft.com/en-us/library/system.attribute.aspx (Sie müssen ein wenig nach unten scrollen)
kay.one
2
Der Link in der Frage wurde aktualisiert. Jetzt ist es die vollständige Liste für 3.5
R. Martinho Fernandes
8
Eigentlich verlinkt das auf die neueste, nicht speziell auf 3.5.
Brian Ortiz
1
Wenn nur die Liste nicht nur eine Liste von Links wäre, sondern der Name und die Beschreibung. Naja. @ BrianOrtiz ist richtig. Die Liste befindet sich in Version 4.5.
Leuchtender
Sie ändern einfach das Framework, auf das Sie abzielen, oben, wo "Andere Versionen" steht.
Novaterata
129

Meine Stimme wäre für Conditional

[Conditional("DEBUG")]
public void DebugOnlyFunction()
{
    // your code here
}

Sie können dies verwenden, um eine Funktion mit erweiterten Debugging-Funktionen hinzuzufügen. wie Debug.Writeist es nur genannt in Debug - Builds, und so können Sie komplexe Debug - Logik außerhalb der Hauptströmung des Programms verkapseln.

Steve Cooper
quelle
5
Ist das nicht dasselbe wie #if DEBUG?
Neil N
10
#Wenn DEBUG bedeutet, dass der Anrufer ihn auch nicht anrufen muss, während der Conditioinal den Anruf verlässt, ihn jedoch zu einem NOP macht, der bei JIT eliminiert wird.
Rangoric
23
Außerdem verwenden Sie normalerweise #if DEBUG für Aufrufe und [Bedingt] für Methoden . Wenn Sie also eine Debugging-Methode 100 Mal aufrufen, ist das Deaktivieren eine einzelne Codeänderung, nicht 100.
Steve Cooper
13
Rangorics Kommentar ist subtil falsch (zumindest für C #): Die Methode ist unverändert enthalten; Die Anrufstelle selbst wird weggelassen. Dies hat einige Auswirkungen: Parameter werden nicht ausgewertet, und die bedingte Methode ist unverändert in der Ausgabe des Compilers enthalten. Sie können dies mit Reflexion überprüfen. msdn.microsoft.com/en-us/library/aa664622.aspx blogs.msdn.com/b/jmstall/archive/2007/10/15/…
Mark Sowul
97

Ich benutze immer das DisplayName, Descriptionund DefaultValueAttribute über öffentliche Eigenschaften meiner Benutzersteuerungen, benutzerdefinierten Steuerelemente oder jede Klasse I durch einen Eigenschaftenraster bearbeiten werden. Diese Tags werden vom .NET PropertyGrid verwendet, um den Namen, das Beschreibungsfeld und fettgedruckte Werte zu formatieren, die nicht auf die Standardwerte festgelegt sind.

[DisplayName("Error color")]
[Description("The color used on nodes containing errors.")]
[DefaultValue(Color.Red)]
public Color ErrorColor
{
    ...
} 

Ich wünschte nur, IntelliSense von Visual Studio würde das DescriptionAttribut berücksichtigen, wenn kein XML-Kommentar gefunden wird. Es würde vermeiden, denselben Satz zweimal wiederholen zu müssen.

Anthony Brien
quelle
3
Ich kann nicht glauben, dass niemand darauf hingewiesen hat, Descriptionbis Sie .. Es ist das hilfreichste für mich, wenn es mit Aufzählungen verwendet wird ..
Nawfal
68

[Serializable]wird ständig zum Serialisieren und Deserialisieren von Objekten zu und von externen Datenquellen wie XML oder von einem Remote-Server verwendet. Mehr dazu hier.

Gilligan
quelle
Es wird tatsächlich auf ein Pseudoattribut verwiesen, da C # ein Metadatenflag für [Serializable]
ausgibt
1
Obwohl sehr nützlich [Serializable] ist alles andere als perfekt. Es erfordert viel zu viel Basteln und Ausprobieren, um das gewünschte Ergebnis zu erzielen.
Shoosh
Ich werde diesen Shoosh unterstützen!
John Bubriski
System.NonSerializedAttribute ist nützlich, wenn Sie mehr Kontrolle über die automatische Serialisierung wünschen.
CSharper
Als Randnotiz möchte ich hinzufügen, dass die Leistung der integrierten .Net-Serialisierung ziemlich schlecht ist, etwa 2 oder 3 Größenordnungen langsamer als handgefertigter Code.
Redcalx
57

Im Hofstadtschen Geist ist das [Attribute]Attribut sehr nützlich, da Sie so Ihre eigenen Attribute erstellen. Ich habe Attribute anstelle von Schnittstellen verwendet, um Plugin-Systeme zu implementieren, Beschreibungen zu Enums hinzuzufügen, mehrere Versendungen und andere Tricks zu simulieren.

C. Lawrence Wenham
quelle
13
Hört sich cool an! Würde es Ihnen etwas ausmachen, einige Beispiele für das Plugin-System und die Enum-Beschreibungen zu zeigen? Das sind beide Dinge, an deren Umsetzung ich interessiert bin!
John Bubriski
46

Hier ist der Beitrag über das interessante Attribut InternalsVisibleTo . Grundsätzlich ahmt es die Zugriffsfunktionen von C ++ - Freunden nach. Es ist sehr praktisch für Unit-Tests.

Xrost
quelle
7
Meinst du nicht praktisch, um einen Unit-Test für etwas zu hacken, das nicht getestet werden konnte / sollte?
the_drow
@the_drow: Sie sprechen über "private Accessoren": msdn.microsoft.com/en-us/library/ms184807%28v=vs.80%29.aspx
habakuk
@habakuk: Nicht wirklich. Es gibt Fälle, in denen interne Klassen für Unit-Tests ausgesetzt werden sollten, normalerweise aufgrund eines schlechten Designs.
the_drow
2
@the_drow: Ich würde nicht sagen, dass InternalsVisibleTo für Unit-Tests böse ist. Sie können kleinere "Einheiten" erstellen und testen, die außerhalb Ihres Projekts nicht sichtbar sind (dies hilft Ihnen, eine saubere und kleine API zu haben). Aber wenn Sie "private Accessoren" benötigen, um etwas zu testen, stimmt wahrscheinlich etwas nicht.
Habakuk
10
@the_drow Ich bin nicht einverstanden mit Ihrer Behauptung, internaldie nicht öffentlich ist. Es ist in der zu testenden Assembly öffentlich und sollte Unit-getestet werden, damit andere Klassen in der Assembly die Korrekturfunktionalität übernehmen können. Wenn Sie es nicht als Unit-Test ausführen, müssen Sie seine Funktionen in allen konsumierenden Klassen testen.
Tvanfosson
28

Ich würde vorschlagen [TestFixture]und [Test]- aus der nUnit- Bibliothek.

Unit-Tests in Ihrem Code bieten Sicherheit beim Refactoring und bei der kodifizierten Dokumentation.

Adrian Wible
quelle
26
[XmlIgnore]

Auf diese Weise können Sie (in jeder XML-Serialisierung) übergeordnete Objekte ignorieren, die sonst beim Speichern Ausnahmen verursachen würden.

Jimi
quelle
25

Es ist nicht gut benannt, wird im Framework nicht gut unterstützt und sollte keinen Parameter erfordern, aber dieses Attribut ist ein nützlicher Marker für unveränderliche Klassen:

[ImmutableObject(true)]
Neil Whitaker
quelle
6
Laut Dokumentation nur zur Entwurfszeit (leider) verwendet.
Hans
1
Da dies nur Entwurfszeit ist, ist es vielleicht besser, eine eigene ImmutableObjectAttributeKlasse zu erstellen - zumindest könnten Sie den Parameter entfernen.
Roy Tinker
25

Ich verwende das [ThreadStatic]Attribut gerne in Kombination mit Thread- und Stack-basierter Programmierung. Wenn ich beispielsweise einen Wert möchte, den ich mit dem Rest einer Anrufsequenz teilen möchte, der jedoch außerhalb des Bandes ausgeführt werden soll (dh außerhalb der Aufrufparameter), kann ich so etwas verwenden.

class MyContextInformation : IDisposable {
    [ThreadStatic] private static MyContextInformation current;

    public static MyContextInformation Current {
        get { return current; }
    }

    private MyContextInformation previous;


    public MyContextInformation(Object myData) {
       this.myData = myData;
       previous = current;
       current = this;
    }

    public void Dispose() {
       current = previous;
    }
}

Später in meinem Code kann ich dies verwenden, um kontextbezogenen Kontextinformationen für Personen bereitzustellen, die meinem Code nachgeschaltet sind. Beispiel:

using(new MyContextInformation(someInfoInContext)) {
   ...
}

Mit dem ThreadStatic-Attribut kann ich den Aufruf nur auf den betreffenden Thread beschränken, um das unordentliche Problem des Datenzugriffs über Threads hinweg zu vermeiden.

Ajaxx
quelle
und wie kann man dann darauf zugreifen? Verstehen Sie den Punkt Ihres Verwendungsbeispiels hier nicht. Können Sie erklären?
Beachwalker
@Beachwalker Current sollte statisch sein, jetzt bearbeitet. Jetzt können Sie darauf zugreifen MyContextInformation.Current, um den aktiven Kontext auf dem Stapel abzurufen. Dies ist ein sehr gutes Konzept, das in bestimmten Fällen von unserer (meiner Firma) Engine für viele Zwecke verwendet wird.
Felix K.
23

Das DebuggerHiddenAttribute , mit dem das Eindringen in Code vermieden werden kann, der nicht debuggt werden sollte.

public static class CustomDebug
{
    [DebuggerHidden]
    public static void Assert(Boolean condition, Func<Exception> exceptionCreator) { ... }
}

...

// The following assert fails, and because of the attribute the exception is shown at this line
// Isn't affecting the stack trace
CustomDebug.Assert(false, () => new Exception()); 

Außerdem wird verhindert, dass Methoden in der Stapelverfolgung angezeigt werden. Dies ist nützlich, wenn eine Methode nur eine andere Methode umschließt:

[DebuggerHidden]
public Element GetElementAt(Vector2 position)
{
    return GetElementAt(position.X, position.Y);
}

public Element GetElementAt(Single x, Single y) { ... }

Wenn Sie jetzt aufrufen GetElementAt(new Vector2(10, 10))und bei der umschlossenen Methode ein Fehler auftritt, zeigt der Aufrufstapel nicht die Methode an, die die Methode aufruft, die den Fehler auslöst.

Felix K.
quelle
21

DesignerSerializationVisibilityAttributeist sehr nützlich. Wenn Sie eine Runtime-Eigenschaft in ein Steuerelement oder eine Komponente einfügen und nicht möchten, dass der Designer sie serialisiert, verwenden Sie sie wie folgt:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
    get { return baz; }
    set { baz = value; }
}
Konfigurator
quelle
4
Sehr nützlich für WinForms-Komponenten. Verwendung in Verbindung mit [Browsable (false)]
Mark Heath
3
Guter Punkt - [Browsable(false)]ist erforderlich, um es vor dem Benutzer des Designers zu verbergen, wo [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]es erforderlich ist, damit es nicht serialisiert wird.
Konfigurator
17

Nur wenige Attribute erhalten Compiler-Unterstützung, aber eine sehr interessante Verwendung von Attributen ist in AOP: PostSharp verwendet Ihre maßgeschneiderten Attribute, um IL in Methoden einzufügen , sodass alle Arten von Fähigkeiten möglich sind ... log / trace sind triviale Beispiele - aber einige andere gute Beispiele sind Dinge wie die automatische INotifyPropertyChanged-Implementierung ( hier ).

Einige, die auftreten und direkt auf den Compiler oder die Laufzeit auswirken :

  • [Conditional("FOO")] - Aufrufe dieser Methode (einschließlich Argumentauswertung) erfolgen nur, wenn das Symbol "FOO" während der Erstellung definiert wird
  • [MethodImpl(...)] - wird verwendet, um ein paar Dinge wie Synchronisation, Inlining anzuzeigen
  • [PrincipalPermission(...)] - wird verwendet, um Sicherheitsüberprüfungen automatisch in den Code einzufügen
  • [TypeForwardedTo(...)]- Wird verwendet, um Typen zwischen Assemblys zu verschieben, ohne die Aufrufer neu zu erstellen

Für Dinge, die manuell durch Reflexion überprüft werden - ich bin ein großer Fan der System.ComponentModelAttribute; Dinge wie [TypeDescriptionProvider(...)], [TypeConverter(...)]und [Editor(...)]die das Verhalten von Typen in Datenbindungsszenarien (dh dynamische Eigenschaften usw.) vollständig ändern können.

Marc Gravell
quelle
15

Wenn ich einen Crawl zur Codeabdeckung durchführen würde, wären diese beiden meiner Meinung nach die besten:

 [Serializable]
 [WebMethod]
FlySwat
quelle
15
[WebMethod] wird verwendet, um eine Methode zu dekorieren, die in einem Webdienst verfügbar gemacht wird. [Serializable] markiert Ihre Objekte so, dass sie für Zwecke wie die Weitergabe an App-Domänen serialisiert werden können.
Kev
15

Ich habe das in [DataObjectMethod]letzter Zeit benutzt. Es beschreibt die Methode, damit Sie Ihre Klasse mit der ObjectDataSource (oder anderen Steuerelementen) verwenden können.

[DataObjectMethod(DataObjectMethodType.Select)] 
[DataObjectMethod(DataObjectMethodType.Delete)] 
[DataObjectMethod(DataObjectMethodType.Update)] 
[DataObjectMethod(DataObjectMethodType.Insert)] 

Mehr Info

wusher
quelle
12

In unserem aktuellen Projekt verwenden wir

[ComVisible(false)]

Es steuert den Zugriff eines einzelnen verwalteten Typs oder Mitglieds oder aller Typen innerhalb einer Assembly auf COM.

Mehr Info

Ahmed
quelle
12
[TypeConverter(typeof(ExpandableObjectConverter))]

Weist den Designer an, die Eigenschaften zu erweitern, die Klassen (Ihres Steuerelements) sind.

[Obfuscation]

Weist Verschleierungswerkzeuge an, die angegebenen Aktionen für eine Baugruppe, einen Typ oder ein Element auszuführen. (Obwohl Sie normalerweise eine Assembly-Ebene verwenden[assembly:ObfuscateAssemblyAttribute(true)]

Chris S.
quelle
1
Ich habe es erraten, war aber falsch. Das Attribut "Verschleierung" ist nur ein Hinweis für Obfsucatoren von Drittanbietern. Der Compiler verschleiert standardmäßig nichts.
Dan spielt
@ DanNeely kostenlos für Visual Studio Pro / Ultimate-Benutzer!
Chris S
4
Wenn Sie sich auf die DotFuscator Community Edition beziehen, ist das Schutzniveau so niedrig, dass es bestenfalls kaum für irgendetwas zählt.
Dan spielt
@ricovox Ich habe eine Zusammenfassung hinzugefügt
Chris S
9

Die Attribute, die ich am häufigsten verwende, beziehen sich auf die XML-Serialisierung.

XmlRoot

XmlElement

XmlAttribute

usw...

Sehr nützlich, wenn Sie schnell und schmutzig XML analysieren oder serialisieren möchten.

Brannon
quelle
8

Als mittelständischer Entwickler mag ich

System.ComponentModel.EditorBrowsableAttribute Ermöglicht es mir, Eigenschaften auszublenden, damit der UI-Entwickler nicht mit Eigenschaften überfordert ist, die er nicht sehen muss.

System.ComponentModel.BindableAttributeEinige Dinge müssen nicht datengebunden sein. Dies verringert wiederum die Arbeit, die die Benutzeroberflächenentwickler leisten müssen.

Ich mag auch das DefaultValue, was Lawrence Johnston erwähnt hat.

System.ComponentModel.BrowsableAttributeund die Flagswerden regelmäßig verwendet.

Ich benutze System.STAThreadAttribute System.ThreadStaticAttribute bei Bedarf.

Apropos. Ich diese sind für alle .NET Framework-Entwickler genauso wertvoll.

ElGringoGrande
quelle
8

[EditorBrowsable(EditorBrowsableState.Never)]Mit dieser Option können Sie Eigenschaften und Methoden in IntelliSense ausblenden, wenn sich das Projekt nicht in Ihrer Lösung befindet. Sehr hilfreich, um ungültige Flows für fließende Schnittstellen zu verbergen. Wie oft möchten Sie GetHashCode () oder Equals ()?

Mit MVC [ActionName("Name")]können Sie eine Get-Aktion und eine Post-Aktion mit derselben Methodensignatur ausführen oder Bindestriche im Aktionsnamen verwenden, die sonst nicht möglich wären, ohne eine Route dafür zu erstellen.

smdrager
quelle
8

Ich halte es für wichtig, hier zu erwähnen, dass die folgenden Attribute ebenfalls sehr wichtig sind:

STAThreadAttribute 

Gibt an, dass das COM-Threading-Modell für eine Anwendung Single-Threaded-Apartment (STA) ist.

Dieses Attribut wird beispielsweise in Windows Forms-Anwendungen verwendet:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

Und auch ...

SuppressMessageAttribute

Unterdrückt die Meldung einer bestimmten Regelverletzung durch ein statisches Analysetool und ermöglicht die mehrfache Unterdrückung eines einzelnen Code-Artefakts.

Zum Beispiel:

[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isChecked")]
[SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "fileIdentifier")]
static void FileNode(string name, bool isChecked)
{
    string fileIdentifier = name;
    string fileName = name;
    string version = String.Empty;
}
Eric Javier Hernandez Saura
quelle
Wird STAThread verwendet, um zu verhindern, dass Ihre Anwendung beim Start versehentlich eine andere Instanz von sich selbst abschaltet?
Leuchtend
7

Hier ist eine kurze Liste der vordefinierten Attribute, die ich tatsächlich in einem großen Projekt verwende (~ 500.000 LoCs), grob sortiert nach Verwendungshäufigkeit:

Flags, Serializable, WebMethod, COMVisible, TypeConverter, Conditional, ThreadStatic, Obsolete, InternalsVisibleTo, DebuggerStepThrough.

Eldritch Rätsel
quelle
2
+1 für ThreadStatic, überrascht, dass es bisher niemand erwähnt hat, und auch für den statistischen Ansatz
staafl
6

Ich generiere eine Datenentitätsklasse über CodeSmith und verwende Attribute für eine Validierungsroutine. Hier ist ein Beispiel:

/// <summary>
/// Firm ID
/// </summary>
[ChineseDescription("送样单位编号")]
[ValidRequired()]
public string FirmGUID
{
    get { return _firmGUID; }
    set { _firmGUID = value; }
}

Und ich habe eine Utility-Klasse für die Validierung basierend auf den Attributen, die an die Datenentitätsklasse angehängt sind. Hier ist der Code:

namespace Reform.Water.Business.Common
{
/// <summary>
/// Validation Utility
/// </summary>
public static class ValidationUtility
{
    /// <summary>
    /// Data entity validation
    /// </summary>
    /// <param name="data">Data entity object</param>
    /// <returns>return true if the object is valid, otherwise return false</returns>
    public static bool Validate(object data)
    {
        bool result = true;
        PropertyInfo[] properties = data.GetType().GetProperties();
        foreach (PropertyInfo p in properties)
        {
            //Length validatioin
            Attribute attribute = Attribute.GetCustomAttribute(p,typeof(ValidLengthAttribute), false);
            if (attribute != null)
            {
                ValidLengthAttribute validLengthAttribute = attribute as ValidLengthAttribute;
                if (validLengthAttribute != null)
                {
                    int maxLength = validLengthAttribute.MaxLength;
                    int minLength = validLengthAttribute.MinLength;
                    string stringValue = p.GetValue(data, null).ToString();
                    if (stringValue.Length < minLength || stringValue.Length > maxLength)
                    {
                        return false;
                    }
                }
            }
            //Range validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRangeAttribute), false);
            if (attribute != null)
            {
                ValidRangeAttribute validRangeAttribute = attribute as ValidRangeAttribute;
                if (validRangeAttribute != null)
                {
                    decimal maxValue = decimal.MaxValue;
                    decimal minValue = decimal.MinValue;
                    decimal.TryParse(validRangeAttribute.MaxValueString, out maxValue);
                    decimal.TryParse(validRangeAttribute.MinValueString, out minValue);
                    decimal decimalValue = 0;
                    decimal.TryParse(p.GetValue(data, null).ToString(), out decimalValue);
                    if (decimalValue < minValue || decimalValue > maxValue)
                    {
                        return false;
                    }
                }
            }
            //Regex validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRegExAttribute), false);
            if (attribute != null)
            {
                ValidRegExAttribute validRegExAttribute = attribute as ValidRegExAttribute;
                if (validRegExAttribute != null)
                {
                    string objectStringValue = p.GetValue(data, null).ToString();
                    string regExString = validRegExAttribute.RegExString;
                    Regex regEx = new Regex(regExString);
                    if (regEx.Match(objectStringValue) == null)
                    {
                        return false;
                    }
                }
            }
            //Required field validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRequiredAttribute), false);
            if (attribute != null)
            {
                ValidRequiredAttribute validRequiredAttribute = attribute as ValidRequiredAttribute;
                if (validRequiredAttribute != null)
                {
                    object requiredPropertyValue = p.GetValue(data, null);
                    if (requiredPropertyValue == null || string.IsNullOrEmpty(requiredPropertyValue.ToString()))
                    {
                        return false;
                    }
                }
            }
        }
        return result;
    }
}
}
Ming Yeh
quelle
6

[DeploymentItem("myFile1.txt")] MSDN Doc on DeploymentItem

Dies ist sehr nützlich, wenn Sie anhand einer Datei testen oder die Datei als Eingabe für Ihren Test verwenden.

Kevin Driedger
quelle
5

[System.Security.Permissions.PermissionSetAttribute] Ermöglicht die Anwendung von Sicherheitsaktionen für ein PermissionSet auf Code mithilfe deklarativer Sicherheit.

// usage:
public class FullConditionUITypeEditor : UITypeEditor
{
    // The immediate caller is required to have been granted the FullTrust permission.
    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    public FullConditionUITypeEditor() { }
}
CSharper
quelle