加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用Rosyln将switch块重写为if / else

发布时间:2020-12-15 08:08:30 所属栏目:百科 来源:网络整理
导读:我是roslyn的新手所以我正在寻找一些指针或示例代码来开始做我想要的. 我有很多与此类似的代码(它是由工具生成的) switch (boolVariable){ case false: { str = "blahblah"; break; } case true: { str = "somethingelse"; break; } default: { str = "ughth
我是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();
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读