2015-06-16 45 views
9

Attualmente sto lavorando per migliorare la mia sensazione di codifica, quindi ho iniziato ad aggiungere alcuni metodi di estensione ai tipi che sto usando.Come mostrare un suggerimento specifico in Visual Studio


Ho capito che sto facendo la stessa azione abbastanza spesso sempre con gli stessi attributi.

voglio mostrare questo suggerimento quando qualcuno chiama ReplaceNewLine("|"):

Il carattere che si desidera rimuovere è |. Utilizzare invece l'estensione RemoveNewLine() senza attributi.

Ho provato con l'attributo [Obsolete(...)], ma questo è stato visualizzato ogni volta che ho chiamato la funzione.

La mia domanda è: come posso mostrare un suggerimento specifico basato sul mio input in Visual Studio?

Codice:

public static class StringExtension 
{ 
    public static string ReplaceNewLine(this string s) 
    { 
     return s.Replace("|", Environment.NewLine); 
    } 

    // show hint if c is | 
    public static string ReplaceNewLine(this string s, string c) 
    { 
     return s.Replace(c, Environment.NewLine); 
    } 
} 

apposizione:

  • Ovviamente il suggerimento può avere il codice Obsolete (0618/CS0618) quando sia dimostrato, ma che non è importante per me . Voglio solo avere il suggerimento mostrato!
  • Sto lavorando con C# 6.0, .NET 4.6 e Visual Studio 2015 RC.
+0

Un plug-in ReSharper può essere una soluzione? –

+0

@Thomas No, mi dispiace ma un plug-in ReSharper non sarà una soluzione adatta per me, poiché non lo uso. Dovrebbe essere fatto interamente con codice in Visual Studio senza aggiungere/installare programmi aggiuntivi. Ma grazie comunque ... – cramopy

+0

Hai provato a utilizzare un metodo Wrapper attorno a 2 metodi privati, uno che è obsoleto, ma viene chiamato solo se l'input è "|"? – Eris

risposta

3

In Visual Studio 2015 questo è possibile utilizzando un Roslyn Diagnostic (e una correzione opzionale). Il nuovo editor di codice di Visual Studio 2015 utilizza Roslyn per fare tutto ciò che sta analizzando e ora il motore Code Analaysis, Metrics and Refactoring è basato su di esso.

Un esempio di implementazione di tale ispezione è given on the Roslyn github page. Un'implementazione completa sarebbe un po 'troppo per una risposta qui su StackOverflow, in quanto comporta una serie di passaggi da eseguire e ammonta a un tutorial completo, ma questo tutorial completo di something similar is given here. e potrebbe essere la base per il tuo lavoro. (fai altre domande più tardi). Codice per standard rules that ship with the product can be found in the Roslyn GitHub as well.

Questo codice dovrebbe portarti vicino, ma non l'ho provato. Creare uno standard diagnostico & correzione secondo la totorial Roslyn SDK e sostituire le Initialize e AnalyzeNode metodi con (sostituire lo spazio dei nomi con il proprio):

public override void Initialize(AnalysisContext context) 
{ 
    context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression); 
} 

private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context) 
{ 
    InvocationExpressionSyntax invocationExpression = context.Node as InvocationExpressionSyntax; 
    IMethodSymbol methodSymbol = context.SemanticModel.GetSymbolInfo(invocationExpression).Symbol as IMethodSymbol; 

    if (
     methodSymbol != null 
     && methodSymbol.Name == "ReplaceNewline" 
     && methodSymbol.ContainingNamespace.Name == "MySampleFix" 
     && methodSymbol.OriginalDefinition.Parameters.Length == 1) 
    { 
     if (invocationExpression.ArgumentList.Arguments.Count() == 1) 
     { 
      LiteralExpressionSyntax arg = 
       invocationExpression.ArgumentList.Arguments[0].Expression as LiteralExpressionSyntax; 

      if (arg != null && arg.Token.ValueText == "|") 
      { 
       Diagnostic.Create(Rule, invocationExpression.GetLocation()); 
      } 
     } 
    } 
} 

Se si vuole fare qualcosa che sia compatibile con le versioni precedenti di Visual Studio puoi scegliere di scrivere una regola di analisi del codice personalizzata. Questo example rule prende l'input per una chiamata a Regex.Match e Regex.Replace e fornisce un avviso quando non viene compilato. Sarebbe ancora più semplice dare un avvertimento quando è una stringa costante.

Le estensioni di Visual Studio come Resharper e CodeRush offrono un SDK che può fare cose simili a FxCop, ma si incorporano nell'IDE come fa Roslyn. Potrebbe essere un'opzione per te adottare questo approccio.

Se si desidera qualcosa nell'editor di codice che non utilizza alcuna estensione o personalizzazione, quindi aggiungere uno <remark /> al codedoc è quanto più si può fare. Nel peggiore dei casi potresti inserire un metodo nel metodo Debug.Assert(input != "|");, in questo modo gli sviluppatori riceveranno un avviso tempestivo (in fase di sviluppo/debug) che stanno usando la tua API in modo errato.

+0

Se persino riesci a fornire un esempio, la risposta sarà perfetta! – cramopy

+0

Non sono ancora il re delle regole di Roslyn (ancora) e l'esempio fornito potrebbe non essere il migliore disponibile. dovrebbe darti abbastanza per iniziare e fare domande successive. – jessehouwing

+0

grazie per l'esempio !! : D – cramopy

-3

Usa virgolette singole

return s.Replace('|', Environment.NewLine); 
+1

Hai completamente frainteso la domanda. – slugster

+0

hai letto anche la domanda ?? – cramopy

1

non penso che sia possibile, solo con l'eccezione di

commento enfatico

:)

/// <summary> 
/// Replace specific char with <see cref="Environment.NewLine"/> 
/// </summary> 
/// <param name="s">input</param> 
/// <param name="c">If the char is "|", use the extension method without any parameter instead (<see cref="StringExtension.ReplaceNewLine()" />).</param> 
/// <returns>something with maybe new lines.</returns> 
public static string ReplaceNewLine(this string s, string c) {...} 

Non so qualsiasi altro modo per produrre suggerimenti in puro Visual Studio, wi th eccezione di #warning msg (e #pragma), ma sono condizionati solo da parametri di costruzione predefiniti (come #IF DEBUG ecc.) e passano direttamente all'elenco degli errori.

Btw & solo per divertimento: è possibile risolvere il tuo esempio con l'aggiunta di valore predefinito

public static class StringExtension 
{ 
    public static string ReplaceNewLine(this string s, string c = "|") 
    { 
     return s.Replace(c, Environment.NewLine); 
    } 
} 

Edit:jessehouwing risposta è molto meglio, tutta questa risposta è stata più o meno una battuta su commenti vigorose :)

+2

Fai attenzione ai "valori predefiniti" perché sono piuttosto malvagi. Il valore predefinito è in realtà compilato nel binario chiamante e se si decide di modificare l'impostazione predefinita in un secondo momento, tutti gli assembly che chiamano quel metodo devono essere ricompilati per utilizzare il nuovo valore. – jessehouwing

+0

Oh, chiamare binario? Non sapevo ... –

+0

Sì, in questo modo è una funzione del compilatore e non una funzione del linguaggio. è cattivo** ;). – jessehouwing

Problemi correlati