2016-05-20 9 views
5

Gibt es eine Möglichkeit, eine C# 6-Funktion mit einem Roslyn-Diagnoseanalysator zu erkennen?Erkennen von C# 6-Funktionen mit Roslyn

Ich habe eine Lösung, die in einigen Dateien aus einem Projekt verbindet, die C# 6 Funktionen nicht verwenden können, also möchte ich einen Fehler nur für diese Dateien machen. Um klar zu sein - ich kann das ganze Projekt nicht auf C# 5 setzen, nur einige Dateien sind tabu.

Ich kann versuchen, bestimmte Funktionen zu erfassen, aber es ist umständlich und fragte mich, ob es einen schnelleren Weg gibt?

+1

Als eine Alternative ist das wahrscheinlich viel einfacher zu implementieren: Führen Sie einfach einen Build mit einem C# 5-Compiler für dieses Projekt als Teil Ihres Build-Prozesses. Ob dies ein benutzerdefiniertes Build-Ereignis oder ein Teil Ihres CI ist, liegt bei Ihnen. – Rob

+0

@Rob Ich denke wirklich, das ist der Weg, genau hier zu gehen. –

+0

@Rob Ich habe nur einige Dateien in diesem Projekt von einem anderen verknüpft, diese sollten diese Funktionen nicht verwenden. Der Rest könnte sie benutzen. –

Antwort

2

Sie diesen Walker Funktionen zur Erkennung C# 6 Syntax verwenden:

public class CSharp6FeaturesWalker : CSharpSyntaxWalker 
{ 
    public bool CSharp6Features { get; private set; } 

    public CSharp6FeatureWalker() 
    { 
    } 

    public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node) 
    { 
     if (node.ExpressionBody != null) 
     { 
      CSharp6Features = true; 
     } 
     else if (node.Initializer != null) 
     { 
      CSharp6Features = true; 
     } 
     base.VisitPropertyDeclaration(node); 
    } 

    public override void VisitMethodDeclaration(MethodDeclarationSyntax node) 
    { 
     if (node.ExpressionBody != null) 
     { 
      CSharp6Features = true; 
     } 
     base.VisitMethodDeclaration(node); 
    } 

    public override void VisitOperatorDeclaration(OperatorDeclarationSyntax node) 
    { 
     if (node.ExpressionBody != null) 
     { 
      CSharp6Features = true; 
     } 
     base.VisitOperatorDeclaration(node); 
    } 

    public override void VisitConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax node) 
    { 
     if (node.ExpressionBody != null) 
     { 
      CSharp6Features = true; 
     } 
     base.VisitConversionOperatorDeclaration(node); 
    } 

    public override void VisitIndexerDeclaration(IndexerDeclarationSyntax node) 
    { 
     if (node.ExpressionBody != null) 
     { 
      CSharp6Features = true; 
     } 
     base.VisitIndexerDeclaration(node); 
    } 

    public override void VisitConditionalAccessExpression(ConditionalAccessExpressionSyntax node) 
    { 
     CSharp6Features = true; 
     base.VisitConditionalAccessExpression(node); 
    } 

    public override void VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) 
    { 
     CSharp6Features = true; 
     base.VisitInterpolatedStringExpression(node); 
    } 

    public override void VisitCatchFilterClause(CatchFilterClauseSyntax node) 
    { 
     CSharp6Features = true; 
     base.VisitCatchFilterClause(node); 
    } 
} 

Leider ist es nicht möglich festzustellen, ob die Datei auf 6 Version geschrieben oder nicht nur auf Syntaxprüfungen basieren, weil einige Funktionen ist inhalt abhing wie nameof Operator (es sowohl spezielle oder übliche Methode sein kann)

Zum Testen von C# 6-Features können Sie this file aus dem ANTLR-Grammatik-Repository verwenden.

+0

Danke, das scheint der beste Weg zu sein! –

+0

Sie haben 'nameof()' bereits als Hürde genannt, also würde ich "using static", "Dictionary-Initialisierer", "erwarten" in 'catch' und' finally' Blöcke hinzufügen, und vielleicht noch etwas, das ich vergessen habe. Es sollte auf jeden Fall darauf hingewiesen werden, dass die vorgestellte Lösung nur die Grundlagen abdeckt (obwohl zugegebenermaßen die gebräuchlichsten Anwendungen sind).Sie können dies jedoch mit den meisten dieser anderen Änderungen auch erweitern. –

1

Ich glaube, der beste Weg, dies zu tun ist, die erweiterten Build-Optionen zu verwenden. Wechseln Sie zu Ihren Projekteigenschaften und wählen Sie die Registerkarte "Erstellen". In der unteren rechten Ecke dieser Registerkarte (möglicherweise müssen Sie nach unten scrollen) sollten Sie eine Schaltfläche "Erweitert" sehen. Klicken Sie das und Sie werden diesen Dialog erhalten:

Advanced Options

Wie Sie sehen, können Sie das Sprachniveau für ein bestimmtes Projekt ändern C# 5.0 sein. Sobald Sie das tun, und Sie versuchen, zu verwenden, sagen wir, String-Interpolation, werden Sie mit einem Fehler angezeigt werden:

enter image description here

+0

Ich denke, ich war nicht sehr klar (es ist ein sehr seltsames Projekt) - nur einige Dateien aus einem Projekt sollten nicht C# 6 Funktionen, nicht das ganze Projekt verwenden, so wird dies nicht funktionieren. Danke für die Hilfe! –

+0

@RobertIvanc, aber ich verstehe nicht, warum Sie kein separates Projekt für diese bestimmten Dateien erstellen. Scheint genau der richtige Anwendungsfall für die Projekttrennung. –

+1

Ja, es scheint, als wäre Ihre Frage "Diese bestimmten Dateien sind in ein anderes Projekt eingebunden, das nicht C# 6 verwenden kann." Dann markieren Sie dieses andere Projekt als nicht in der Lage, C# 6 zu verwenden ...? –