我是roslyn的新手所以我正在寻找一些指针或示例代码来开始做我想要的.
switch (boolVariable) { case false: { str = "blahblah"; break; } case true: { str = "somethingelse"; break; } default: { str = "ughthiswouldnevergethit"; break; } }
我想要做的是检测然后将语法重写为更高效和开发人员友好的东西
if(boolVariable) { str = "somethingelse"; } else { str = "blahblah"; }
基本上我想要优化所有布尔值的开关.
解决方法
你必须使用CSharpSyntaxRewriter,下面是实现它的代码(简单的情况下,你可以从中扩展)
(您应该下载Syntax Visualizer扩展或转到简单的在线版本CSharp SyntaxTree 以了解有关语法树的更多信息)
string code = ReadText("Case6.cs"); // get source code as string for a class var tree = CSharpSyntaxTree.ParseText(code); CompilationUnitSyntax root = (CompilationUnitSyntax)tree.GetRoot(); Compilation compilation = CSharpCompilation.Create("assembly",SyntaxTrees: new[] { tree },references: new[] { mscorlib = MetadataReference.CreateFromAssembly(typeof(object).Assembly),MetadataReference.CreateFromAssembly(typeof(Stack<>).Assembly) }); var semanticModel = compilation.GetSemanticModel(tree); var myRewriter = new MyRewriter(semanticModel); var result = myRewriter.Visit(tree.GetRoot()); var str = result.ToString(); // below are classes for Rewriter public class MyRewriter : CSharpSyntaxRewriter { private SemanticModel semanticModel; public MyRewriter(SemanticModel semanticModel) { this.semanticModel = semanticModel; } public override SyntaxNode VisitSwitchStatement(SwitchStatementSyntax node) { var result = base.VisitSwitchStatement(node); // detect your case: // first check if the expression in switch is bool type? var typeInfo = semanticModel.GetTypeInfo(node.Expression); if(typeInfo.Type.SpecialType != SpecialType.System_Boolean) { return result; } // okie we make the conversion here // find true statement var trueSection = node.Sections .First(f => f.Labels.First().ToString().Contains("true")); var falseSection = node.Sections .First(f => f.Labels.First().ToString().Contains("false")); var trueStatement = trueSection.Statements.Count == 1 ? trueSection.Statements.First() : SyntaxFactory.Block(trueSection.Statements); var falseStatement = falseSection.Statements.Count == 1 ? falseSection.Statements.First() : SyntaxFactory.Block(falseSection.Statements); var ifStatement = SyntaxFactory.IfStatement(node.Expression,trueStatement,SyntaxFactory.ElseClause(falseStatement)); //NOTE that: this class will remove all break statements // it will not be correct if break in loop,you can base on that to // write more accurately var breakRemover = new BreakRemover(); result = breakRemover.Visit(ifStatement); return result; } } public class BreakRemover : CSharpSyntaxRewriter { public override SyntaxNode VisitBreakStatement(BreakStatementSyntax node) { // should add further check to make sure break statement is in // switch,the idea is find closest ancestor must be switch (not // for,foreach,while,dowhile) return SyntaxFactory.EmptyStatement(); } }