2009-01-28 4 views
8

Quelles sont les applications géniales pour les attributs personnalisés dans le code CLR/C# que vous avez fait ou entendus? De nouvelles utilisations intéressantes des attributs standard sont également possibles! Puisque les annotations de Java semblent être les mêmes que celles de CLR, les utilisations des annotations Java sont également valides.Utilisations cool des attributs ou des annotations (CLR ou Java)?

Répondre

12
  • postsharp, qui utilise des attributs pour injecter du code (AOP)?
  • [TypeDescriptionProvider] qui peut être utilisé pour fournir un modèle de propriété d'exécution personnalisée - soit des propriétés complètement différentes, ou peut-être faster ones

et quelques fondamentaux qui sont souvent négligés:

+0

Bon sang, tu m'as battu! –

+0

+1 pour PrincipalPermissionAttribute - Je ne peux pas croire que je l'ai fait manuellement avant. – Botz3000

8

Bien qu'il ne s'agisse pas strictement de C#, j'ai trouvé une utilisation intéressante des annotations Java (= attributs C#) pour marquer les affectations des étudiants. Chaque semestre, je programme un robot de marquage pour les étudiants, et il s'avère que les étudiants de première année ne semblent pas être capables de suivre les instructions avec précision, ce qui, bien sûr, fait échouer le robot de marquage. Donc, ce que je fais est de parcourir leur code, de trouver toutes les méthodes qui ne répondent pas à la spécification et de les corriger. Ensuite, j'ai mis une annotation (= attribut) sur chacune des méthodes qui étaient erronées, en disant au robot de marquage de les marquer. C'est probablement le moyen le plus simple et le plus direct de le faire, je pense.

+0

Avoir à corriger manuellement le code de chaque élève ne semble pas simple, cependant? –

+0

C'est vrai, mais dans notre cas c'était simple parce que nous avions une politique où si le travail d'un étudiant ne compilait pas, il n'était pas marqué. Tout ce que j'ai fait, c'est enlever la méthode et la remplacer par un bout. –

1

J'ai un cas, où je veux présenter l'implémentation réelle d'une interface en tant que données. Cela peut se faire via Reflection bien sûr, mais en utilisant un attribut spécifique sur les membres que je veux exposer en tant que données, je peux encapsuler le travail nécessaire pour le faire.

Le résultat final est que je crée mon implémentation, décore les membres désirés et ensuite je peux interroger les membres à la fois par le code et les données sans avoir à faire le code de réflexion dans chaque cas.

1

Parfois, j'utilise des attributs pour décorer des classes ou des méthodes et j'utilise la réflexion pour obtenir les données 'attribuées'.

Peut-être un peu difficile à expliquer, mais la dernière chose pour laquelle j'ai utilisé les attributs, est dans un système où j'ai quelques entités dans une base de données. Chaque entité a une sorte de «code», et chaque entité peut également avoir des règles d'interprétation.

Dans mon projet, j'ai une classe d'entité, qui représente une entité qui existe dans la base de données, et j'ai également un ensemble de classes 'Rule'. Une classe Rule contient la logique d'interprétation d'une entité donnée. Pour "lier" une certaine "règle" (interprétation) à une instance spécifique de mon entité, j'ai créé un attribut personnalisé.

Je décore ma classe 'Rule' avec cet attribut, et à travers l'attribut, je définis pour quelle entité il s'agit d'une règle. Ensuite, lorsque je charge une entité à partir de la base de données, j'injecte la règle correcte dans cette entité.

Un peu de code pour rendre les choses claires:

public class MyEntity 
{ 
    public string Code 
    { 
     get; 
     private set; 
    } 

    public bool IsValidFor(...) 
    { 
     IRule rule = RuleRegistry.GetRuleFor(this); 

     if(rule.IsValid()) ... 
    } 

} 

[RuleAttrib("100")] 
public class MyRule : IRule 
{ 
    public bool IsValid() 
    { 
    } 
} 

Ceci est juste un petit exemple, mais je pense que vous allez attraper la dérive. L'attribut RuleAttrib sur la classe MyRule indique qu'il s'agit d'une règle qui doit être appliquée à l'instance de MyClass qui a un code "100".

L'instance RuleRegistry est capable de récupérer l'IRule correcte pour l'entité actuelle (en utilisant la réflexion).

Un autre exemple où j'ai attributs utilisés, en combinaison avec PostSharp, est la mise en œuvre d'un système de « verrouillage »: http://fgheysels.blogspot.com/2008/08/locking-system-with-aspect-oriented.html

+0

Idée intéressante là-bas –

1

nous utilisons des annotations personnalisées java pour marquer des fins spéciales de certaines méthodes, principalement ciblées aux développeurs:

  • @ScriptingAPI - code marques qui est exposée dans le cadre de notre API de script (met en garde contre les développeurs que les changements pourraient avoir une incidence sur l'API publique)
  • @Transaction - méthodes de marques sur t La façade de base de données qui commence/commet une transaction (nous avons une classe de gestionnaire de transactions dédiée qui respecte cette annotation)
  • @NeedsAttentionToSupportFoo - si nous connaissons cette fonctionnalité Foo est une exigence que nous devrons aborder dans un proche avenir, nous utilisez une annotation pour marquer le code que nous aurons besoin de toucher pour le supporter, c'est-à-dire quand nous rencontrons un morceau de code qui nous fait penser "ah, ça va devoir être changé pour supporter Foo", nous l'annotons. Si l'implémentation de Foo est reportée ou n'arrivera jamais, il est plus facile de supprimer l'annotation que de revenir aux optimisations pré-matures éparpillées tout autour du code.

Un autre bon exemple d'utilisation d'une annotation personnalisée est traité dans this java specialist newsletter: appliquer un constructeur public sans-args dans toutes les sous-classes.

3

Jetez un coup d'œil à xUnit et voyez comment les attributs sont utilisés pour marquer les tests unitaires pour le comportement attendu ainsi que pour alimenter les données en tests. Les attributs sont utilisés de manière plus significative que MSTest ou NUnit.

De Samples\TestMethodExtensibility\Example.cs:

public class Example 
{ 
    static int val; 

    [RepeatTest(5, Timeout=250)] 
    public void RepeatingTestMethod() 
    { 
     Thread.Sleep(100); 
     Assert.Equal(2, 2); 

     if (val == 0) 
     { 
      val++; 
      Thread.Sleep(1000); 
     } 
    } 
} 

De test.xunit.extensions\DataTheories\TheoryAttributeTests.cs:

internal class TestMethodCommandClass 
{ 
    public static IEnumerable<object[]> EmptyData 
    { 
     get { return new object[0][]; } 
    } 

    public static IEnumerable<object[]> NullData 
    { 
     get { return null; } 
    } 

    public static IEnumerable<object[]> TheoryDataProperty 
    { 
     get { yield return new object[] { 2 }; } 
    } 

    [Theory, PropertyData("EmptyData")] 
    public void EmptyDataTheory() { } 

    [Theory, PropertyData("NullData")] 
    public void NullDataTheory() { } 

    [Theory, OleDbData(
     @"Provider=Microsoft.Jet.OleDb.4.0; Data Source=DataTheories\UnitTestData.xls; Extended Properties=Excel 8.0", 
     "SELECT x, y, z FROM Data")] 
    public void TestViaOleDb(double x, 
          string y, 
          string z) { } 

    [Theory, PropertyData("TheoryDataProperty")] 
    public void TestViaProperty(int x) { } 

    [Theory, ExcelData(@"DataTheories\UnitTestData.xls", "SELECT x, y, z FROM Data")] 
    public void TestViaXls(double x, 
          string y, 
          string z) { } 

} 

Pour plus de détails voir:

http://www.codeplex.com/xunit

+0

Ah oui, c'est ce que je considère comme l'une des utilisations les plus appropriées des annotations. –

2

nunit bien sûr

les utilisations des attributs ont été priées par kent beck:

NUnit 2.0 est un excellent exemple de conception idiomatique. La plupart des utilisateurs du port xUnit ne font que translittérer la version Smalltalk ou Java. C'est aussi ce que nous avons fait avec NUnit au début. Cette nouvelle version est NUnit comme cela aurait été fait si elle avait été faite en C# pour commencer.

source: http://www.nunit.org/

1

Château de ActiveRecord utilise des attributs. Il cache une partie de la complexité d'installation de NHibernate en décorant vos objets Model avec des attributs indiquant les classes et les champs qui devraient être conservés dans la base de données (et comment). Le composant de validation utilise également des attributs pour ajouter une validation basée sur un modèle dans ActiveRecord et la pile Monorail.

Questions connexes