【问题标题】:Adding new field declaration to class with Roslyn使用 Roslyn 向类添加新字段声明
【发布时间】:2017-12-22 23:05:47
【问题描述】:

有什么方法可以使用 roslyn 将成员添加到类中?我要补充:

public int number {get;set;}

更新 我使用了这段代码:

       PropertyDeclarationSyntax o =  
       SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName("public  
       System.Windows.Forms.Timer"), "Ticker { get; set; }");

       var newRoot = root.ReplaceNode(oldMethod, oldMethod.AddMembers(o));
       newRoot = Formatter.Format(newRoot, new AdhocWorkspace());

       File.WriteAllText(file, newRoot.ToFullString());

但是结果是这样的:

   public class ClassChild
{
    public int n;
    private int n2;

    public void method1()
    {
        string c = "";
        Console.WriteLine();
    }

public System.Windows.Forms.TimerTicker { get; set; }
}

}

我想内联 public System.Windows.Forms.TimerTicker { get;放; } 与 n 和 n2。我该怎么做?

【问题讨论】:

  • 你能扩展你想要实现的目标吗?创建用于添加值的分析器\修复器或独立实用程序(用于构建过程,for.ex.)?
  • 我想修复一个添加新字段的类。在过去,我成功地向方法添加了一条新语句: /MethodDeclarationSyntax updateMethod = oldMethod.AddBodyStatements(ex); //var updatedRoot = root.ReplaceNode(oldMethod, updateMethod).NormalizeWhitespace();我想做同样的事情
  • 你能帮帮我吗?
  • 是的,我做了,但它们不起作用

标签: c# roslyn roslyn-code-analysis


【解决方案1】:

查看代码

    private PropertyDeclarationSyntax MakeProperty()
    {
        string name = "n";

        // Create an auto-property
        var property =
            SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName("int"), name)
            .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
            .AddAccessorListAccessors(
                SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
                SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
            );

        return property;
    }

    private async Task<Document> AddProperty(Document document, ClassDeclarationSyntax classeDecl, CancellationToken cancellationToken)
    {
        var root = await document.GetSyntaxRootAsync(cancellationToken);
        var newClass = classeDecl.AddMembers(MakeProperty());
        return document.WithSyntaxRoot(root.ReplaceNode(classeDecl, newClass));
    }

自动属性生成示例取自this问题。

【讨论】:

    【解决方案2】:

    就个人而言,我更喜欢这种技术:

    public static class SyntaxHelpers
    {
        public static T GenerateClassNode<T>(string decl) where T : CSharpSyntaxNode
        {
            var declaration = SyntaxFactory.ParseCompilationUnit(
                " public class FSM { \r\n" +
                $"{decl}\r\n" +
                " }} \r\n");
    
            var field = declaration.Members[0].DescendantNodes().First() as T;
            return field;
        }
    }
    

    然后你可以如下使用它:

    string log4NetLoggerDeclaration =
                        "private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);";
    
    var log4NetDeclarationStatement = SyntaxHelpers.GenerateClassNode<FieldDeclarationSyntax>(log4NetLoggerDeclaration);
    
    string declarationString = log4NetLoggerDeclaration.ToString();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-12
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-31
      • 2012-03-01
      • 2019-03-21
      相关资源
      最近更新 更多