我在roslyn的语法树中有一个ClassDeclarationSyntax。 我这样读了:
var tree = SyntaxTree.ParseText(sourceCode);
var root = (CompilationUnitSyntax)tree.GetRoot();
var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>();
标识符仅包含类的名称,但不包含有关命名空间的信息,因此缺少fullType名称。像“MyClass”但是noch“Namespace1.MyClass”
获取语法的名称空间/ FulltypeName的推荐方法是什么?
答案 0 :(得分:5)
你可以使用我写的助手类来做到这一点:
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<T>(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<T>(syntaxNode, out result);
}
catch
{
return false;
}
}
}
这里没有任何过于复杂的事情......命名空间将是&#34; up&#34;语法树(因为类包含在命名空间中)所以你只需要旅行&#34; up&#34;语法树,直到找到命名空间并将其附加到ClassDeclarationSyntax
的标识符。
答案 1 :(得分:1)
试试此代码
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();
}
答案 2 :(得分:1)
基于the answer by Ronald,我添加了对以下内容的支持:嵌套名称空间,结构和泛型。
它使用generics CLR naming convention来允许输出用作Compilation.GetTypeByMetadataName()的输入
option 1
答案 3 :(得分:1)
使用模式匹配+递归时,还有一种优雅的方法:
def job(hours,rate):
if hours < 40:
sm = hours * rate
print(sm)
elif hours > 40:
sm = 40 * rate
ov = ((hours - 40) * rate) * 0.5
tt = sm + ov
print(tt)
a = float(input())
b = float(input())
print(job(a,b))
print("Fine")
答案 4 :(得分:0)
以下是我获取命名空间的方法。您必须稍微修改我的代码:
public static async Task<NamespaceDeclarationSyntax> 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();
}
答案 5 :(得分:0)
我知道我已经很晚了,但是我偶然发现one of given the answers在我不得不处理嵌套类的情况下不起作用。因此,这是一种也可以处理嵌套类的方法:
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<string>();
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;
}
}
答案 6 :(得分:0)
另一个答案。.该实用工具类支持嵌套的名称空间和嵌套的类。
public static class SyntaxNodeHelper
{
public static string GetPrefix(SyntaxNode member)
{
if (member == null) {
return "";
}
StringBuilder sb = new StringBuilder();
SyntaxNode node = member;
while(node.Parent != null) {
node = node.Parent;
if (node is NamespaceDeclarationSyntax) {
var namespaceDeclaration = (NamespaceDeclarationSyntax) node;
sb.Insert(0, ".");
sb.Insert(0, namespaceDeclaration.Name.ToString());
} else if (node is ClassDeclarationSyntax) {
var classDeclaration = (ClassDeclarationSyntax) node;
sb.Insert(0, ".");
sb.Insert(0, classDeclaration.Identifier.ToString());
}
}
return sb.ToString();
}
}