2010-08-20 10 views
8

Le nouveau motif de Resharper 5 semble très puissant, même s'il faut un peu de bricolage pour savoir comment l'utiliser.Comment utilisez-vous la fonctionnalité de recherche de motif dans ReSharper 5?

Pour ceux qui ne sont pas familiers avec cette fonctionnalité, il vous permet de rechercher des modèles spécifiques dans votre code. Des instances de tels motifs peuvent éventuellement être remplacées par une alternative. Dans IntelliJ, cela s'appelait la recherche structurelle et le remplacement. C'est beaucoup plus puissant que la simple recherche/remplacement RegEx.

Je voudrais collecter une série de modèles que les gens utilisent pour que je puisse apprendre à mieux utiliser cette fonctionnalité.

Je propose que chaque réponse comprennent:

  • une brève introduction de la justification du motif
  • un exemple de ce qu'il correspondrait
  • un exemple en option d'un remplacement
  • XML généré en exportant le modèle pour que d'autres puissent l'essayer aussi
+0

Je suis nouveau à ReSharper 5, mais voulez-vous dire les cas où ReSharper sera (par exemple) est recommandé d'utiliser LINQ en place d'un foreach qui existe uniquement pour localiser un sous-ensemble d'objets à l'intérieur une collection? – JYelton

+0

@JYelton - ReSharper recommandera ce genre de chose hors de la boîte. La fonctionnalité dont je parle ici est celle qui vous permet d'ajouter vos propres suggestions/conseils/avertissements/erreurs. Si vous voulez que R # repère certains types de choses qui ne le sont pas déjà, vous pouvez les programmer vous-même. Voir quelques-uns des exemples que j'ai postés ci-dessous. –

+0

Merci, cela explique le motif correspondant pour moi. Cela ressemble à une excellente référence. – JYelton

Répondre

1

Redémarrer un chronomètre

.NET 4 introduit la méthode System.Diagnostics.Stopwatch.Restart() qui peut ranger votre code.

Avant:

stopwatch.Reset(); 
stopwatch.Start(); 

Après:

stopwatch.Restart(); 

XML:

<CustomPatterns> 
    <Pattern Severity="SUGGESTION"> 
    <Comment>Use Restart method for System.Diagnostics.Stopwatch</Comment> 
    <ReplaceComment>Use Restart method for System.Diagnostics.Stopwatch</ReplaceComment> 
    <ReplacePattern>$stopwatch$.Restart();</ReplacePattern> 
    <SearchPattern><![CDATA[$stopwatch$.Reset(); 
$stopwatch$.Start();]]></SearchPattern> 
    <Params /> 
    <Placeholders> 
     <ExpressionPlaceholder Name="stopwatch" ExpressionType="System.Diagnostics.Stopwatch" ExactType="True" /> 
    </Placeholders> 
    </Pattern> 
</CustomPatterns> 
10

assorti d'un [Flags] bit ENUM

.NET 4 introduit la méthode System.Enum.HasFlag qui peut ranger votre code.

Avant:

(myValue & MyFlagsEnum.Foo) == MyFlagsEnum.Foo 

Après:

myValue.HasFlag(MyFlagsEnum.Foo) 

XML:

<CustomPatterns> 
    <Pattern Severity="SUGGESTION"> 
    <Comment>Can condense using 'Enum.HasFlag' method</Comment> 
    <ReplaceComment>Replace bit matching with 'Enum.HasFlag'</ReplaceComment> 
    <ReplacePattern>$myValue$.HasFlag($target$)</ReplacePattern> 
    <SearchPattern><![CDATA[($myValue$ & $target$) == $target$]]></SearchPattern> 
    <Params /> 
    <Placeholders> 
     <ExpressionPlaceholder Name="myValue" ExpressionType="System.Enum" ExactType="False" /> 
     <ExpressionPlaceholder Name="target" ExpressionType="System.Enum" ExactType="False" /> 
    </Placeholders> 
    </Pattern> 
</CustomPatterns> 
+0

Nice. J'ai toujours écrit une méthode privée pour le faire car je détestais me répéter, mais maintenant je sais mieux! :) –

3

JetBrains offre une Sample Pattern Catalog for Structural Search and Replace pour téléchargement contenant 17 modèles:

  • bloc 'try/finally' peut être converti en 'utilisant' déclaration
  • Méthode StringBuilder.Append peut être converti en StringBuilder.AppendFormat
  • Comparaison avec le vrai est redondant
  • Instruction conditionnelle est redondant code
  • est injoignable
  • « si » bloc est jamais exécuté
  • branches identiques dans une instruction conditionnelle
  • affectation de composé redondant avec | = opérateur
  • Affectation composée redondante avec & = opérateur
  • Attribut de composé redondant ment avec | = opérateur (alternative cas)
  • affectation composée redondante avec & = opérateur (cas de remplacement)
  • d'initialisation redondant à bloc faux et l'état
  • initialisation redondante au bloc vrai et l'état
  • Méthode Array.CreateInstance peut être remplacé par une expression de création de matrice
  • Méthode Array.CreateInstance peut être remplacée par une création matrice bidimensionnelle expression
  • d'utilisation redondante de GetType() == typeof() avec un type de valeur
  • Méthode OfType peut être utilisé pour le type basé filtrage
+0

Ne pas trouvé le téléchargement. – brgerner

+1

@brgerner, merci. J'ai mis à jour le lien maintenant. –

+0

Merci pour la mise à jour du lien! – brgerner

0

Par exemple, Microsoft recommande (et Analyse du code/FxCop génère avertissements appropriés) si vous faites une comparaison entre une valeur de chaîne et une chaîne vide, pour utiliser la méthode String.IsNullOrEmpty().

http://david.gardiner.net.au/2010/02/resharper-5-structural-search-and.html

+1

R # fait cela dès la sortie de la boîte, à partir de la version 5.1.1757.11 au moins. Ce serait bien d'avoir un support pour la conversion en 'string.IsNullOrWhitespace'. –

1

Celui-ci est différent. J'ai découvert plus tard dans mon projet que les assertions de mbunit qui comparent les valeurs de propriété aux énumérations ne rendent pas de gentils messages en utilisant la syntaxe AssertEx.That.

Je créé un modèle pour trouver ceci:

AssertEx.That(() => myVariable.Status == MyEnum.Ok); 

... et le remplacer par ceci:

Assert.AreEqual(MyEnum.Ok, myVariable.Status); 

Voici le modèle:

<Pattern Severity="WARNING"> 
<Comment>AssertEx.That asserts for enum values don't give nice error msgs</Comment> 
<ReplaceComment>Replace AssertEx.That asserts for enum values with trad Assert.AreEqual for better error msgs</ReplaceComment> 
<ReplacePattern>Assert.AreEqual($enum$,$variable$.$property$)</ReplacePattern> 
<SearchPattern><![CDATA[AssertEx.That(() => $variable$.$property$ == $enum$]]></SearchPattern> 
<Params /> 
<Placeholders> 
    <ExpressionPlaceholder Name="enum" ExpressionType="System.Enum" ExactType="False" /> 
    <IdentifierPlaceholder Name="variable" Type="" ExactType="False" RegEx="" CaseSensitive="True" /> 
    <IdentifierPlaceholder Name="property" Type="" ExactType="False" RegEx="" CaseSensitive="True" /> 
</Placeholders> 

4

Enlever si envelopper autour de si corps.

Exemple:

Ce code:

if (ok) 
{ 
    DoNextStep(); 
} 

sera remplacé par:

DoNextStep(); 

corps Alors seulement si reste.

Le XML:

<Pattern Severity="HINT"> 
    <Comment>if</Comment> 
    <ReplaceComment>Remove enclosing if</ReplaceComment> 
    <ReplacePattern>$body$</ReplacePattern> 
    <SearchPattern>if($condition$){$body$}</SearchPattern> 
    <Params /> 
    <Placeholders> 
     <StatementPlaceholder Name="body" Minimal="-1" Maximal="-1" /> 
     <ExpressionPlaceholder Name="condition" ExpressionType="System.Boolean" ExactType="True" /> 
    </Placeholders> 
    </Pattern> 
1

Supprimer enfermant accolades autour d'un corps.

Exemple:

ce code:

foreach (int i in arr) 
    { 
     DoNextStep(); 
    } 

sera remplacé (par Ctrl + L pour supprimer la ligne foreach et ensuite exécuter ce modèle pour supprimer les accolades) par:

DoNextStep(); 

Donc, seul le corps des accolades reste après avoir tapé autour de deux raccourcis.

Le XML:

<Pattern Severity="HINT"> 
    <Comment>Curly braces with body</Comment> 
    <ReplaceComment>Remove braces</ReplaceComment> 
    <ReplacePattern>$body$</ReplacePattern> 
    <SearchPattern>{$body$}</SearchPattern> 
    <Params /> 
    <Placeholders> 
    <StatementPlaceholder Name="body" Minimal="-1" Maximal="-1" /> 
    </Placeholders> 

1

Pour 'comme' fonte.

Exemple:

Ce code:

string s = (string) o; 

sera remplacé par:

string s = o as string; 

Alors maintenant, vous avez le 'comme' fonte au lieu de fonte régulière.

Le XML:

<Pattern Severity="HINT"> 
    <Comment>Cast</Comment> 
    <ReplaceComment>To 'as' cast</ReplaceComment> 
    <ReplacePattern>$exp$ as $type$</ReplacePattern> 
    <SearchPattern>($type$)$exp$</SearchPattern> 
    <Params /> 
    <Placeholders> 
    <TypePlaceholder Name="type" Type="" ExactType="True" /> 
    <ExpressionPlaceholder Name="exp" ExpressionType="" ExactType="True" /> 
    </Placeholders> 
</Pattern> 
1

Pour lancer régulièrement.

Exemple:

Ce code:

string s = o as string; 

sera remplacé par:

string s = (string) o; 

Alors maintenant, vous avez la distribution régulière au lieu de 'comme' casting.

Le XML:

<Pattern Severity="HINT"> 
    <Comment>Cast (as)</Comment> 
    <ReplaceComment>To regular cast</ReplaceComment> 
    <ReplacePattern>($type$)$exp$</ReplacePattern> 
    <SearchPattern>$exp$ as $type$</SearchPattern> 
    <Params /> 
    <Placeholders> 
    <ExpressionPlaceholder Name="exp" ExpressionType="" ExactType="True" /> 
    <TypePlaceholder Name="type" Type="" ExactType="True" /> 
    </Placeholders> 
</Pattern> 
+0

C'est quelque chose que j'espérais voir ajouté à R # depuis un moment maintenant. Je n'avais pas envisagé de le faire via SSR. Merci! L'opération inverse peut aussi être utile (cast à 'as '). –

+0

@DrewNoakes J'ai ajouté l'opération inverse aussi. Voir la réponse * Pour 'as' cast * (http://stackoverflow.com/a/9330016/1187616) – brgerner

+0

Nice. Avoir un vote :) –