我正在使用 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()
{
}
}
关于c# - 使用 Roslyn 将类(class)成员添加到特定位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74751968/