C #: Comment implémenter et utiliser un atsortingbut NotNull et CanBeNull

Je veux que les programmeurs et moi-même sachions qu’une méthode ne veut pas de null et si vous lui envoyez de toute façon null , le résultat ne sera pas joli.

Il y a un NotNullAtsortingbute et un CanBeNullAtsortingbute dans les bibliothèques partagées Lokad , dans l’espace de noms Lokad.Quality .

Mais comment ça marche? J’ai regardé le code source de ces deux atsortingbuts et ça ressemble à ceci:

 [AtsortingbuteUsage(AtsortingbuteTargets.Method | AtsortingbuteTargets.Parameter | AtsortingbuteTargets.Property | AtsortingbuteTargets.Delegate | AtsortingbuteTargets.Field, AllowMultiple = false, Inherited = true)] [NoCodeCoverage] public sealed class NotNullAtsortingbute : Atsortingbute { } [AtsortingbuteUsage(AtsortingbuteTargets.Method | AtsortingbuteTargets.Parameter | AtsortingbuteTargets.Property | AtsortingbuteTargets.Delegate | AtsortingbuteTargets.Field, AllowMultiple = false, Inherited = true)] [NoCodeCoverage] public sealed class CanBeNullAtsortingbute : Atsortingbute { } 

Deux classes vides héritant de Atsortingbute . Comment sont-ils utilisés? Devez-vous rechercher la documentation xml et savoir qu’elle existe? Parce que j’ai essayé à la fois de faire ma propre copie de l’atsortingbut et d’utiliser la version de Lokad, mais quand j’ai essayé d’envoyer directement un null directement, je n’ai reçu aucun message. Ni de ReSharper ni de VS. Ce à quoi je m’attendais en fait. Mais comment sont-ils utilisés? Puis-je faire en sorte que VS génère des avertissements pour moi si j’essaye d’envoyer quelque chose qui est nul là-dedans? Ou est-ce juste utilisé dans une sorte de framework de test? Ou?

A moyen terme, les “contrats de code” (en 4.0) seront une meilleure réponse à cette question. Ils sont disponibles maintenant (avec des licences académiques ou commerciales ), mais seront plus intégrés dans VS2010. Cela peut fournir à la fois une parsing statique et un support d’exécution.

(edit) exemple:

 Contract.RequiresAlways( x != null ); 

Aussi simple que cela … le moteur de contrats de code fonctionne au niveau IL, il peut donc parsingr cela et lancer des avertissements / erreurs à partir du code appelant pendant la construction ou à l’exécution. Pour une compatibilité ascendante, si vous avez un code de validation existant, vous pouvez simplement lui indiquer où se termine la vérification de la validité, et cela fera le rest:

 if ( x == null ) throw new ArgumentNullException("x"); Contract.EndContractBlock(); 

Cela peut être fait soit avec AOP , un conseil vérifiant à l’exécution si un paramètre de méthode est nul et si des valeurs NULL sont autorisées. Voir PostSharp et Spring.NET pour AOP.

En ce qui concerne ReSharper, voir Framework annoté :

Nous avons analysé un grand nombre de bibliothèques de classes .NET Framework, ainsi que NUnit Framework, et les avons annotées via des fichiers XML externes, en utilisant un ensemble d’atsortingbuts personnalisés de l’espace de noms JetBrains.Annotations, en particulier:

  • SsortingngFormatMethodAtsortingbute (pour les méthodes qui prennent des chaînes de format comme parameters)
  • InvokerParameterNameAtsortingbute (pour les méthodes avec des arguments littéraux de chaîne qui doivent correspondre à l’un des parameters de l’appelant)
  • AssertionMethodAtsortingbute (pour les méthodes d’assertion)
  • AssertionConditionAtsortingbute (pour les parameters de condition des méthodes d’assertion)
  • TerminatesProgramAtsortingbute (pour les méthodes qui mettent fin au stream de contrôle)
  • CanBeNullAtsortingbute (pour les valeurs pouvant être nulles)
  • NotNullAtsortingbute (pour les valeurs qui ne peuvent pas être nulles)

Ces annotations concernent ReSharper et sont copiées à partir de l’espace de noms JetBrains.Annotations. Un framework peut les placer dans leur propre espace de nommage, mais ReSharper ne les récupérera PAS automatiquement. Vous devez indiquer à ReSharper d’utiliser l’espace de noms personnalisé dans la boîte de dialog des options. Une fois que vous avez sélectionné le nouvel espace de noms, l’parsing de ReSharper reprendra les atsortingbuts et vous indiquera les points forts et les avertissements.

Comme l’a souligné Anton Gogolev , les atsortingbuts peuvent être créés à l’aide de PostSharp (notez que CodeContract utilise des appels de méthodes statiques dans le corps de la méthode).

MISE À JOUR Février 2013: la nouvelle version 3.0 de PostSharp (actuellement en version bêta) prendra en charge la validation des parameters, des champs et des propriétés

1) L’article validate-parameters-using-atsortingbutes a implémenté

classe publique NotEmpty: ParameterAtsortingbute

classe publique NotNull: ParameterAtsortingbute

[AtsortingbuteUsage (AtsortingbuteTargets.Parameter)]

Classe abstraite publique ParameterAtsortingbute: Atsortingbut

{

 public abstract void CheckParameter(ParameterInfo parameter, object value); 

}

Il nécessite également un atsortingbut de méthode avec un aspect de limite de méthode pour traiter les atsortingbuts de paramètre.

2) Dans le commentaire de l’article, il existe des liens vers une implémentation très similaire pour NonNull / NonEmpty

[return: NonNull] public SomeObject SomeMethod ([NonNull] AnotherObject param1)

Le code source se trouve dans le code google Torch / DesignByContract

3) un autre exemple plus compliqué est décrit dans http://badecho.com/2011/11/validating-method-parameters-with-postsharp/