从Roslyn ClassDeclarationSyntax获取类FullName(包括命名空间)

我在roslyn的语法树中有一个ClassDeclarationSyntax。 我这样看了:

var tree = SyntaxTree.ParseText(sourceCode); var root = (CompilationUnitSyntax)tree.GetRoot(); var classes = root.DescendantNodes().OfType(); 

标识符仅包含类的名称,但不包含有关命名空间的信息,因此缺少fullType名称。 像“MyClass”但是noch“Namespace1.MyClass”

获取语​​法的名称空间/ FulltypeName的推荐方法是什么?

你可以使用我写的助手类来做到这一点:

 NamespaceDeclarationSyntax namespaceDeclarationSyntax = null; if (!SyntaxNodeHelper.TryGetParentSyntax(classDeclarationSyntax, out namespaceDeclarationSyntax)) { return; // or whatever you want to do in this scenario } var namespaceName = namespaceDeclarationSyntax.Name.ToString(); var fullClassName = namespaceName + "." + classDeclarationSyntax.Identifier.ToString(); 

和助手:

 static class SyntaxNodeHelper { public static bool TryGetParentSyntax(SyntaxNode syntaxNode, out T result) where T : SyntaxNode { // set defaults result = null; if (syntaxNode == null) { return false; } try { syntaxNode = syntaxNode.Parent; if (syntaxNode == null) { return false; } if (syntaxNode.GetType() == typeof (T)) { result = syntaxNode as T; return true; } return TryGetParentSyntax(syntaxNode, out result); } catch { return false; } } } 

这里没有任何过于复杂的东西……有意义的是命名空间将“升级”语法树(因为类包含在命名空间中)所以你只需要“向上”语法树,直到找到命名空间并将其附加到ClassDeclarationSyntax的标识符。

试试这个代码

 public static string GetFullName(NamespaceDeclarationSyntax node) { if (node.Parent is NamespaceDeclarationSyntax) return String.Format("{0}.{1}", GetFullName((NamespaceDeclarationSyntax)node.Parent), ((IdentifierNameSyntax)node.Name).Identifier.ToString()); else return ((IdentifierNameSyntax)node.Name).Identifier.ToString(); } 

以下是我获取命名空间的方法。 您必须稍微修改我的代码以适应您的情况:

  public static async Task GetNamespaceAsync(this Document document, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode documentRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var rootCompUnit = (CompilationUnitSyntax)documentRoot; return (NamespaceDeclarationSyntax)rootCompUnit.Members.Where(m => m.IsKind(SyntaxKind.NamespaceDeclaration)).Single(); } 

我知道我在游戏中已经很晚了,但是我偶然发现了一个给出了答案 , 这些答案在我的情况下不起作用,我必须处理嵌套类。 因此,这里有一个方法来处理嵌套类:

 public static class ClassDeclarationSyntaxExtensions { public const string NESTED_CLASS_DELIMITER = "+"; public const string NAMESPACE_CLASS_DELIMITER = "."; public static string GetFullName(this ClassDeclarationSyntax source) { Contract.Requires(null != source); var items = new List(); var parent = source.Parent; while (parent.IsKind(SyntaxKind.ClassDeclaration)) { var parentClass = parent as ClassDeclarationSyntax; Contract.Assert(null != parentClass); items.Add(parentClass.Identifier.Text); parent = parent.Parent; } var nameSpace = parent as NamespaceDeclarationSyntax; Contract.Assert(null != nameSpace); var sb = new StringBuilder().Append(nameSpace.Name).Append(NAMESPACE_CLASS_DELIMITER); items.Reverse(); items.ForEach(i => { sb.Append(i).Append(NESTED_CLASS_DELIMITER); }); sb.Append(source.Identifier.Text); var result = sb.ToString(); return result; } }