2017-10-06 1 views
13

ReSharper est assez intelligent pour savoir que string.Format nécessite un non nul argument de format il me met en garde contre quand j'écris simplementPuis-je enseigner à ReSharper un test nul personnalisé?

_message = string.Format(messageFormat, args); 

messageFormat peut en effet être nul. Dès que j'ajoute une condition pour cette variable:

if (!string.IsNullOrEmpty(messageFormat)) 
{ 
    _message = string.Format(messageFormat, args); 
} 

l'avertissement disparaît. Unfortunatelly il ne pas lorsque j'utilise une méthode d'extension:

if (messageFormat.IsNotNullOrEmpty()) 
{ 
    _message = string.Format(messageFormat, args); // possible 'null' assignment warning 
} 

Ma question est: est-il possible de enseigner ReSharper que ma méthode d'extension a la même signification que !string.IsNullOrEmpty(messageFormat)?

L'extension est définie comme:

public static bool IsNotNullOrEmpty([CanBeNull] this string value) => !IsNullOrEmpty(value); 
+0

ce travail? '' chaîne statique EmptyIfNull (cette chaîne s) { return string.IsNullOrEmpty (s)? "": s; } '' alors '' _message = string.Format (messageFormat.EmptyIfNull(), args), '' – dumetrulo

Répondre

8

Oui il y a. Vous devez utiliser le ReSharper annotations pour guider l'analyse de ReSharper. Vous utilisez déjà [CanBeNull] alors ils sont déjà définis dans votre projet.

Celui que vous serez intéressé par est ContractAnnotationAttribute:

annotations du contrat vous permettent de définir les résultats attendus pour les entrées données, ou en d'autres mots, définir les dépendances entre le type de référence et les arguments booléens d'une fonction et sa valeur de retour. Le mécanisme des annotations de contrat permet de créer des API qui pourraient être consommées de manière plus simple et plus sûre.

Voici comment l'utiliser:

[ContractAnnotation("null => false")] 
public static bool IsNotNullOrEmpty(this string value) 
    => !string.IsNullOrEmpty(value); 

L'argument est une carte d'entrées possibles (null, notnull, true, false) aux sorties (null, notnull, canbenull, true, false, halt):

Voici un autre exemple:

[ContractAnnotation("foo: null => halt; bar: notnull => notnull")] 
public string Frob(string foo, string bar) 

signifie que la fonction décorée ne reviendra (ou jeter une exception) si vous passez null au paramètre foo et garantit qu'il ne reviendra pas null si vous passez une valeur non nulle à bar.

The documentation décrit la syntaxe plus en détail.


est ici ce qui se passe sans l'attribut:

before

L'avertissement disparaît après l'ajouter:

after

+0

Cela ressemble beaucoup! J'utilisais déjà 'ContractAnnotation's ici et là mais je ne savais pas que ça marcherait aussi pour ce cas. Je pense aussi que ce contrat n'est pas tout à fait correct car "notnull" ne signifie pas nécessairement "vrai". Ce pourrait être 'string.Empty' qui est' notnull' mais 'false' de toute façon. – t3chb0t

+0

@ t3chb0t oups, vous avez raison, le contrat est faux, 'null => false' est assez –