Attributs les plus utiles [fermé]

784

Je sais que les attributs sont extrêmement utiles. Il y en a des prédéfinies, telles que celles [Browsable(false)]qui vous permettent de masquer les propriétés dans l'onglet Propriétés. Voici une bonne question expliquant les attributs: Que sont les attributs dans .NET?

Quels sont les attributs prédéfinis (et leur espace de noms) que vous utilisez réellement dans vos projets?

puissant
la source
27
Quelle question? , la page entière regorge de belles réponses avec de merveilleuses explications. Pendant que je lis ceci, j'ai acquis une expérience comme interviewer de nombreux experts à propos de leur point de vue. +100 pour la question.
Muthu Ganapathy Nathan
Je suis d'accord, des questions comme celle-ci sont parmi les plus précieuses - rend tellement moins utile qu'il soit fermé.
David Thielen

Réponses:

669

[DebuggerDisplay]peut être très utile pour voir rapidement la sortie personnalisée d'un type lorsque vous passez la souris sur l'instance du type pendant le débogage. exemple:

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

Voici à quoi cela devrait ressembler dans le débogueur:

texte alternatif

En outre, il convient de mentionner que l' [WebMethod]attribut avec le CacheDurationjeu de propriétés peut éviter l'exécution inutile de la méthode de service Web.

Vivek
la source
62
Wow, c'est vraiment bon à savoir. J'ai généralement accompli la même chose en remplaçant ToString, mais c'est mieux.
Brian
17
Soyez prudent avec cela, il mord beaucoup plus gros morceau de votre CPU que ToString.
Nikola Radosavljević
1
Vous pouvez également l'utiliser pour afficher le résultat des méthodes. Cela peut créer une expérience de débogage assez déroutante si la méthode (ou la propriété-get) a des effets secondaires.
Øyvind Skaar
4
@ NikolaRadosavljević ne prendrait-il que la puissance du processeur pendant le débogage
Nickolay Kondratyev
2
@Nickolay Kondratyev: Je ne connais pas tous les tenants et aboutissants, mais vous pouvez jeter un œil dans les meilleures pratiques de service Web suivantes qui peuvent vous amener à certaines conclusions: blogs.msdn.com/b/jaredpar/archive/2011/03/ 18 /…
Nikola Radosavljević
273

System.Obsoleteest l'un des attributs les plus utiles dans le cadre, à mon avis. La possibilité de déclencher un avertissement concernant le code qui ne devrait plus être utilisé est très utile. J'adore avoir un moyen de dire aux développeurs que quelque chose ne devrait plus être utilisé, ainsi que d'avoir un moyen d'expliquer pourquoi et de pointer vers la meilleure / nouvelle façon de faire quelque chose.

Le Conditional attributeest également très pratique pour l'utilisation du débogage. Il vous permet d'ajouter des méthodes dans votre code à des fins de débogage qui ne seront pas compilées lorsque vous générez votre solution pour publication.

Ensuite, il y a beaucoup d'attributs spécifiques aux contrôles Web que je trouve utiles, mais ils sont plus spécifiques et n'ont aucune utilisation en dehors du développement des contrôles serveur à partir de ce que j'ai trouvé.

Dan Herbert
la source
50
Vous pouvez passer "true" comme l'un des paramètres à System.Obsolete, ce qui fait que l'avertissement devient une erreur et donc rompt la génération. Évidemment, cela devrait être fait une fois que vous avez nettoyé tous les avertissements. :)
Adrian Clark
14
Une fois que vous aurez nettoyé tous les avertissements, ne serait-il pas préférable de simplement supprimer la méthode?
Pedro
10
@Pedro: Parfois, vous ne pouvez pas, pour des raisons de compatibilité descendante. S'il est privé et inutilisé, supprimez-le.
Fantius
3
@plinth Lancer une exception serait une mauvaise idée pour de nombreuses raisons, # 1 étant que la principale raison d'utiliser Obsolete () est pour que vous puissiez continuer à travailler le code compilé pendant une phase de transition. Si vous n'autorisez personne à appeler la méthode, pourquoi ne pas simplement la supprimer?
Dan Herbert
17
@plinth C'est pour empêcher un nouveau code d'utiliser la méthode. L'ancien code restera compatible binaire si une méthode est marquée comme obsolète, mais il cessera de fonctionner si vous lancez une exception. Si quelqu'un utilise la réflexion pour contourner le drapeau "Obsolte", alors vous avez de plus gros problèmes ...
Dan Herbert
204

[Flags]est assez pratique. Sucre syntaxique certes, mais quand même plutôt sympa.

[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 souligne quelque chose que je n'avais pas réalisé, et qui atténue plutôt mon enthousiasme pour cet attribut: il n'indique pas au compilateur d'autoriser les combinaisons de bits comme valeurs valides pour les variables d'énumération, le compilateur autorise cela pour les énumérations malgré tout. Mon arrière-plan C ++ à travers ... soupir

Shog9
la source
Alors, que fait exactement l'attribut Flags?
Andrei Rînea
13
J'espère que vous vous rendez compte que l'attribut Flags encombre tout. Il n'est pas nécessaire / utilisé du tout, à l'exception du TypeConverter.
leppie
3
@leppie: ToString () également. Mais ... wow. Pour une raison quelconque, je m'attendais à ce que le comportement des énumérations sans l'attribut soit le même que C ++: ou les valeurs produiraient un entier (ne peut pas être transmis tel quel à la méthode qui attend le paramètre enum). Je vois maintenant que ce n'est pas le cas. Faible ... ok, les énumérations .NET sont nulles.
Shog9
2
[Flags] n'aide vraiment que le débogueur et les fonctions .ToString () à savoir qu'une valeur est potentiellement une combinaison de plusieurs déclarations dans l'énumération. Je ne suis pas sûr, cela pourrait aussi aider Intellisense à utiliser l'énumération plus efficacement.
Kenzi
31
[Flags]a une plus grande utilité que d'être simplement du sucre syntaxique. Lors de l'utilisation de services Web, la sérialisation / dé-sérialisation ne fonctionnera pas si une valeur similaire SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jamest transmise. Sans l' [Flags]attribut, le désérialiseur ne saura pas que la valeur peut être une combinaison de drapeaux. J'ai appris cela à la dure après avoir passé environ deux jours à penser pourquoi ma WCF ne fonctionnait pas.
Anchit
177

J'aime [DebuggerStepThrough]de System.Diagnostics .

C'est très pratique pour éviter de pénétrer dans ces méthodes ou propriétés d'une ligne de ne rien faire (si vous êtes obligé de travailler dans un .Net précoce sans propriétés automatiques). Mettez l'attribut sur une méthode courte ou sur le getter ou le setter d'une propriété, et vous volerez à droite même en appuyant sur "step into" dans le débogueur.

Blair Conrad
la source
5
Tant de fois j'aurais aimé connaître cette propriété
wusher
1
Dommage qu'il soit rompu avec les fermetures - voir gregbeech.com/blogs/tech/archive/2008/10/17/… pour plus d'informations.
Greg Beech
3
Également utile pour tout code WM_Paint que vous connaissez fonctionne :)
Pondidum
@GregBeech Cette URL renvoie une erreur .NET. Chic! :)
smdrager
@smdrager - Cela devait être un problème temporaire, semble fonctionner pour moi aujourd'hui.
Greg Beech
135

Pour ce que ça vaut, voici une liste de tous les attributs .NET . Il y en a plusieurs centaines.

Je ne connais personne d'autre mais j'ai de la RTFM sérieuse à faire!

wprl
la source
33
la liste publiée est pour .net 1.1 voici la liste pour 3.5 msdn.microsoft.com/en-us/library/system.attribute.aspx (vous devez faire défiler un peu)
kay.one
2
Mise à jour du lien dans la question. Maintenant, c'est la liste complète pour 3.5
R. Martinho Fernandes
8
En fait, cela renvoie à la dernière version, et non à la 3.5 en particulier.
Brian Ortiz
1
Maintenant, si seulement la liste n'était pas seulement une liste de liens, mais le nom et la description. Tant pis. @BrianOrtiz a raison. La liste est à la version 4.5.
Luminous
Vous venez de changer le cadre que vous ciblez en haut où il est dit "Autres versions".
Novaterata
129

Mon vote serait pour Conditional

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

Vous pouvez l'utiliser pour ajouter une fonction avec des fonctionnalités de débogage avancées; comme Debug.Write, il est uniquement appelé dans les versions de débogage, et vous permet donc d'encapsuler une logique de débogage complexe en dehors du flux principal de votre programme.

Steve Cooper
la source
5
n'est-ce pas la même chose que de faire #if DEBUG?
Neil N
10
Quelque peu, #if DEBUG signifie que l'appelant doit également ne pas l'appeler, tandis que le Conditioinal quitte l'appel mais en fait un NOP qui est éliminé au JIT.
Rangoric
23
En outre, vous utilisez généralement #if DEBUG autour des appels et [Conditionnel] autour des méthodes . Donc, si vous appelez une méthode de débogage 100 fois, la désactiver est une question de changement de code unique, pas 100.
Steve Cooper
13
Le commentaire de Rangoric est subtilement faux (au moins pour C #): la méthode est incluse non modifiée; le site d'appel lui-même est omis. Cela a quelques implications: les paramètres ne sont pas évalués et la méthode conditionnelle est contenue, non modifiée, dans la sortie du compilateur. Vous pouvez le vérifier avec réflexion. msdn.microsoft.com/en-us/library/aa664622.aspx blogs.msdn.com/b/jmstall/archive/2007/10/15/…
Mark Sowul
97

Je l' utilise toujours DisplayName, Descriptionet les DefaultValueattributs sur les propriétés publiques de mes contrôles utilisateur, les contrôles personnalisés ou toute catégorie , je vais modifier à travers une grille de la propriété. Ces balises sont utilisées par le .NET PropertyGrid pour formater le nom, le panneau de description et les valeurs en gras qui ne sont pas définies sur les valeurs par défaut.

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

Je souhaite juste que IntelliSense de Visual Studio prenne Descriptionen compte l' attribut si aucun commentaire XML n'est trouvé. Cela éviterait d'avoir à répéter deux fois la même phrase.

Anthony Brien
la source
3
Je ne peux pas croire que personne ne vous le fasse remarquer Description.. C'est le plus utile pour moi lorsqu'il est utilisé avec des énumérations ..
nawfal
68

[Serializable]est utilisé tout le temps pour sérialiser et désérialiser des objets vers et depuis des sources de données externes telles que xml ou depuis un serveur distant. Plus d'informations ici.

Gilligan
la source
Il s'agit en fait d'un attribut pseudo, car C # émet un indicateur de métadonnées pour [Serializable], pas une instance d'attribut personnalisé;)
TraumaPony
1
Bien que très utile, [Serializable] est loin d'être parfait. Cela nécessite beaucoup trop de bricolages et d'essais et d'erreurs pour obtenir le résultat souhaité.
shoosh
J'appuie ce shoosh!
John Bubriski
System.NonSerializedAttribute est utile si vous voulez plus de contrôle sur la sérialisation automatique.
CSharper
En guise de remarque, j'ajouterais que les performances de la sérialisation .Net intégrée sont assez médiocres, comme 2 ou 3 ordres de grandeur plus lentement que le code fabriqué à la main.
redcalx
57

Dans l'esprit hofstadtien, l' [Attribute]attribut est très utile, car c'est ainsi que vous créez vos propres attributs. J'ai utilisé des attributs au lieu d'interfaces pour implémenter des systèmes de plugins, ajouter des descriptions à Enums, simuler plusieurs répartitions et autres astuces.

C. Lawrence Wenham
la source
13
Cela paraît bien! Pourriez-vous montrer des exemples du système de plugins et des descriptions d'énumérations? Ce sont les deux choses que je souhaite mettre en œuvre moi-même!
John Bubriski
46

Voici le post sur l'attribut intéressant InternalsVisibleTo . Fondamentalement, il imite la fonctionnalité d'accès aux amis C ++. Il est très pratique pour les tests unitaires.

xrost
la source
7
Vous ne voulez pas dire pratique pour pirater un test unitaire sur quelque chose qui ne peut / ne devrait pas être testé?
the_drow
@the_drow: Vous parlez des «accesseurs privés»: msdn.microsoft.com/en-us/library/ms184807%28v=vs.80%29.aspx
habakuk
@habakuk: Pas vraiment. Il existe des cas où les classes internes doivent être exposées pour les tests unitaires, généralement en raison d'une mauvaise conception.
the_drow
2
@the_drow: Je ne dirais pas que InternalsVisibleTo est mauvais pour les tests unitaires; vous pouvez créer et tester des "unités" plus petites qui ne sont pas visibles en dehors de votre projet (cela vous aide à avoir une api propre et petite). Mais si vous avez besoin d'accesseurs privés pour tester quelque chose, il y a probablement quelque chose qui ne va pas.
habakuk
10
@the_drow Je suis en désaccord avec votre affirmation qui internaln'est pas publique. C'est public au sein de l'assembly qui est testé et doit être testé unitaire afin que les autres classes de l'assembly puissent assumer sa fonctionnalité de correction. Si vous ne le testez pas à l'unité, vous devrez tester ses fonctions dans toutes les classes consommatrices.
tvanfosson
28

Je suggère [TestFixture]et [Test]- de la bibliothèque nUnit .

Les tests unitaires dans votre code offrent une sécurité dans la refactorisation et la documentation codifiée.

Adrian Wible
la source
26
[XmlIgnore]

car cela vous permet d'ignorer (dans toute sérialisation xml) les objets «parents» qui provoqueraient autrement des exceptions lors de l'enregistrement.

jimi
la source
25

Il n'est pas bien nommé, n'est pas bien pris en charge dans le cadre et ne devrait pas nécessiter de paramètre, mais cet attribut est un marqueur utile pour les classes immuables:

[ImmutableObject(true)]
Neil Whitaker
la source
6
Selon les documents, utilisé uniquement au moment du design (malheureusement).
Hans Ke st ing le
1
Étant donné que cela ne concerne que la conception, il serait peut-être préférable de créer votre propre ImmutableObjectAttributeclasse - au moins, vous pouvez éliminer le paramètre.
Roy Tinker
25

J'aime utiliser l' [ThreadStatic]attribut en combinaison avec la programmation basée sur les threads et la pile. Par exemple, si je veux une valeur que je veux partager avec le reste d'une séquence d'appel, mais que je veux le faire hors bande (c'est-à-dire en dehors des paramètres d'appel), je pourrais utiliser quelque chose comme ça.

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;
    }
}

Plus loin dans mon code, je peux l'utiliser pour fournir des informations contextuelles hors bande aux personnes en aval de mon code. Exemple:

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

L'attribut ThreadStatic me permet d'étendre l'appel uniquement au thread en question en évitant le problème compliqué d'accès aux données entre les threads.

Ajaxx
la source
et comment y accéder ensuite? Je ne comprends pas l'intérêt de votre exemple d'utilisation ici. Peux-tu expliquer?
Beachwalker
@Beachwalker Current devrait être statique, modifiez-le maintenant. Vous pouvez maintenant accéder MyContextInformation.Currentpour obtenir le contexte actif sur la pile. C'est quelque chose qui est un très bon concept dans certains cas, notre moteur (mes entreprises) l'utilise à de nombreuses fins.
Felix K.
23

Le DebuggerHiddenAttribute qui permet d'éviter d'entrer dans le code qui ne doit pas être débogué.

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()); 

Cela empêche également d'afficher les méthodes dans la trace de la pile, utile lorsque vous disposez d'une méthode qui encapsule simplement une autre méthode:

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

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

Si vous appelez maintenant GetElementAt(new Vector2(10, 10))et qu'une erreur se produit au niveau de la méthode encapsulée, la pile d'appels n'affiche pas la méthode qui appelle la méthode qui renvoie l'erreur.

Felix K.
la source
21

DesignerSerializationVisibilityAttributeest très utile. Lorsque vous placez une propriété d'exécution sur un contrôle ou un composant et que vous ne voulez pas que le concepteur la sérialise, vous l'utilisez comme ceci:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
    get { return baz; }
    set { baz = value; }
}
89%
la source
4
très utile pour les composants WinForms. utiliser en conjonction avec [Browsable (false)]
Mark Heath
3
Bon point - [Browsable(false)]est nécessaire pour le cacher à l'utilisateur du concepteur, où il [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]est nécessaire pour qu'il ne soit pas sérialisé.
configurateur
17

Seuls quelques attributs sont pris en charge par le compilateur, mais une utilisation très intéressante des attributs est dans AOP: PostSharp utilise vos attributs sur mesure pour injecter IL dans les méthodes, permettant toutes sortes de capacités ... log / trace étant des exemples triviaux - mais quelques autres bons exemples sont des choses comme la mise en œuvre automatique INotifyPropertyChanged ( ici ).

Certaines se produisent et ont un impact direct sur le compilateur ou le runtime :

  • [Conditional("FOO")] - les appels à cette méthode (y compris l'évaluation des arguments) ne se produisent que si le symbole "FOO" est défini pendant la construction
  • [MethodImpl(...)] - utilisé pour indiquer quelques éléments comme la synchronisation, l'inlining
  • [PrincipalPermission(...)] - utilisé pour injecter automatiquement des contrôles de sécurité dans le code
  • [TypeForwardedTo(...)]- utilisé pour déplacer les types entre les assemblys sans reconstruire les appelants

Pour les choses qui sont vérifiées manuellement par réflexion - je suis un grand fan des System.ComponentModelattributs; des choses comme [TypeDescriptionProvider(...)], [TypeConverter(...)]et [Editor(...)]qui peut complètement changer le comportement des types dans les scénarios de liaison de données ( par exemple propriétés dynamiques , etc.).

Marc Gravell
la source
15

Si je devais faire une analyse de couverture de code, je pense que ces deux seraient les meilleurs:

 [Serializable]
 [WebMethod]
FlySwat
la source
15
[WebMethod] est utilisé pour décorer une méthode exposée dans un service Web. [Sérialisable] marque vos objets de manière à ce qu'ils puissent être sérialisés à des fins telles que leur passage sur des domaines d'application.
Kev
15

J'utilise ces [DataObjectMethod]derniers temps. Il décrit la méthode afin que vous puissiez utiliser votre classe avec l'ObjectDataSource (ou d'autres contrôles).

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

Plus d'informations

wusher
la source
12

Dans notre projet actuel, nous utilisons

[ComVisible(false)]

Il contrôle l'accessibilité d'un COM ou d'un type géré individuel, ou de tous les types au sein d'un assembly.

Plus d'informations

Ahmed
la source
12
[TypeConverter(typeof(ExpandableObjectConverter))]

Indique au concepteur d'étendre les propriétés qui sont des classes (de votre contrôle)

[Obfuscation]

Demande aux outils d'obscurcissement d'effectuer les actions spécifiées pour un assemblage, un type ou un membre. (Bien que vous utilisiez généralement un niveau d'assemblage[assembly:ObfuscateAssemblyAttribute(true)]

Chris S
la source
1
J'ai deviné, mais j'avais tort. L'attribut Obfuscation n'est qu'un indice pour les obfsucateurs tiers. Il ne fait rien obscurcir le compilateur par défaut.
Dan est en train de jouer par Firelight le
@DanNeely gratuit pour les utilisateurs de Visual Studio Pro / Ultimate!
Chris S
4
Si vous faites référence à DotFuscator Community Edition, le niveau de protection fourni est si bas qu'au mieux, il compte à peine pour rien.
Dan est en train de jouer par Firelight le
@ricovox J'ai ajouté un résumé
Chris S
9

Les attributs que j'utilise le plus sont ceux liés à la sérialisation XML.

XmlRoot

XmlElement

XmlAttribute

etc...

Extrêmement utile lors de toute analyse ou sérialisation XML rapide et sale.

Brannon
la source
8

Être un développeur de niveau intermédiaire que j'aime

System.ComponentModel.EditorBrowsableAttribute Me permet de masquer les propriétés afin que le développeur de l'interface utilisateur ne soit pas submergé de propriétés qu'il n'a pas besoin de voir.

System.ComponentModel.BindableAttributeCertaines choses n'ont pas besoin d'être liées aux données. Encore une fois, réduit le travail que les développeurs d'interface utilisateur doivent faire.

J'aime aussi ce DefaultValueque Lawrence Johnston a mentionné.

System.ComponentModel.BrowsableAttributeet Flagssont utilisés régulièrement.

J'utilise en System.STAThreadAttribute System.ThreadStaticAttribute cas de besoin.

Au fait. Ces derniers sont tout aussi précieux pour tous les développeurs de framework .Net.

ElGringoGrande
la source
8

[EditorBrowsable(EditorBrowsableState.Never)]vous permet de masquer les propriétés et les méthodes d'IntelliSense si le projet n'est pas dans votre solution. Très utile pour masquer les flux invalides pour les interfaces fluides. À quelle fréquence voulez-vous GetHashCode () ou Equals ()?

Car MVC [ActionName("Name")]vous permet d'avoir une action Get et une action Post avec la même signature de méthode, ou d'utiliser des tirets dans le nom de l'action, ce qui autrement ne serait pas possible sans créer un itinéraire pour celle-ci.

smdrager
la source
8

Je considère qu'il est important de mentionner ici que les attributs suivants sont également très importants:

STAThreadAttribute 

Indique que le modèle de thread COM pour une application est cloisonné (STA).

Par exemple, cet attribut est utilisé dans les applications Windows Forms:

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());
    }
}

Et aussi ...

SuppressMessageAttribute

Supprime le signalement d'une violation de règle d'outil d'analyse statique spécifique, autorisant plusieurs suppressions sur un seul artefact de code.

Par exemple:

[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
la source
STAThread est-il utilisé pour empêcher votre application de tourner accidentellement une autre instance d'elle-même au démarrage?
Luminous
7

En haut de ma tête, voici une liste rapide, grossièrement triée par fréquence d'utilisation, des attributs prédéfinis que j'utilise réellement dans un grand projet (~ 500k LoCs):

Drapeaux, Sérialisable, WebMethod, COMVisible, TypeConverter, Conditionnel, ThreadStatic, Obsolete, InternalsVisibleTo, DebuggerStepThrough.

Eldritch Conundrum
la source
2
+1 pour ThreadStatic, surpris que personne ne l'ait mentionné jusqu'à présent, et aussi pour l'approche statistique
staafl
6

Je génère une classe d'entité de données via CodeSmith et j'utilise des attributs pour une certaine routine de validation. Voici un exemple:

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

Et j'ai obtenu une classe utilitaire pour faire la validation basée sur les attributs attachés à la classe d'entité de données. Voici le 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
la source
6

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

Ceci est vraiment utile si vous testez un fichier ou utilisez le fichier comme entrée pour votre test.

Kevin Driedger
la source
5

[System.Security.Permissions.PermissionSetAttribute] permet d'appliquer des actions de sécurité pour un PermissionSet au code à l'aide de la sécurité déclarative.

// 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
la source