使用 Roslyn 将新字段声明添加到 class
Adding new field declaration to class with Roslyn
有什么方法可以使用 roslyn 将成员添加到 class?我要添加:
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。我该怎么做?
见代码
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));
}
自动 属性 生成示例取自 问题。
就我个人而言,我更喜欢这种技术:
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();
有什么方法可以使用 roslyn 将成员添加到 class?我要添加:
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。我该怎么做?
见代码
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));
}
自动 属性 生成示例取自
就我个人而言,我更喜欢这种技术:
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();