[英]Adding class members into specific locations using Roslyn?
我正在使用ClassDeclarationSyntax.AddMembers()
向類添加方法。 該方法出現在類中,但我想知道如何將方法添加到特定位置。 到目前為止,它們被添加到類末尾的#if
指令中。
羅斯林版本:4.4.0
運行代碼:
var tree = CSharpSyntaxTree.ParseText(@"
namespace Test
{
public class A
{
#if !SILVERLIGHT
public int someField;
#endif
}
}");
var classNode = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First();
var previousWhiteSpacesToken =
SyntaxFactory.Token(SyntaxTriviaList.Empty, SyntaxKind.None, SyntaxTriviaList.Empty);
var method = SyntaxFactory.MethodDeclaration( //
SyntaxFactory.PredefinedType( //
SyntaxFactory.Token(SyntaxKind.IntKeyword)), "CalculateSize") //
.WithModifiers(SyntaxTokenList.Create(previousWhiteSpacesToken)
.Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword))) //
.WithBody(SyntaxFactory.Block()).NormalizeWhitespace();
var newClassNode = classNode.AddMembers(method).NormalizeWhitespace();
Console.WriteLine(newClassNode.ToString());
會得到這樣的結果:
public class A
{
#if !SILVERLIGHT
public int someField;
public int CalculateSize()
{
}
#endif
}
我知道有辦法做到這一點,但這個結果只能保證正確性:
public class A
{
public int CalculateSize()
{
}
#if !SILVERLIGHT
public int someField;
#endif
}
我期待這個結果:
public class A
{
#if !SILVERLIGHT
public int someField;
#endif
public int CalculateSize()
{
}
}
這里的問題是#endif
是關閉類聲明的}
的主要瑣事。 因此,當您只添加一個成員時, #endif
仍然是}
的主要瑣事。
您需要做的是將}
的主要瑣事移動為您要添加的新方法的主要瑣事。
這是您的代碼的修改版本:
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
var tree = CSharpSyntaxTree.ParseText(@"
namespace Test
{
public class A
{
#if !SILVERLIGHT
public int someField;
#endif
}
}");
var classNode = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First();
var previousWhiteSpacesToken =
SyntaxFactory.Token(SyntaxTriviaList.Empty, SyntaxKind.None, SyntaxTriviaList.Empty);
var method = SyntaxFactory.MethodDeclaration( //
SyntaxFactory.PredefinedType( //
SyntaxFactory.Token(SyntaxKind.IntKeyword)), "CalculateSize") //
.WithModifiers(SyntaxTokenList.Create(previousWhiteSpacesToken)
.Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword))) //
.WithBody(SyntaxFactory.Block())
.WithLeadingTrivia(classNode.CloseBraceToken.LeadingTrivia).NormalizeWhitespace(); // copy '}' leading trivia to the new method.
// remove leading trivia from '}', they are moved previously to the new method.
var newClassNode = classNode.WithCloseBraceToken(classNode.CloseBraceToken.WithLeadingTrivia()).AddMembers(method).NormalizeWhitespace();
Console.WriteLine(newClassNode.ToString());
這將打印以下內容(正是您的期望):
public class A
{
#if !SILVERLIGHT
public int someField;
#endif
public int CalculateSize()
{
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.