Roslyn中INamedTypeSymbol.ContainingNamespace.Name返回空字符串的问题
为什么typedata.ContainingNamespace.Name返回空字符串?
主要有三种可能的原因:
目标类型属于全局命名空间
如果你的Type参数对应的类型没有声明在任何namespace中,typedata.ContainingNamespace会指向全局命名空间,而全局命名空间的Name属性本身就是空字符串。可以通过typedata.ContainingNamespace.IsGlobalNamespace验证这一点。误取直接父命名空间而非完整命名空间
若目标类型在嵌套命名空间(如System.Collections.Generic.List)中,ContainingNamespace.Name仅返回直接父命名空间的名称(如Generic),而非完整路径。如果类型本身在顶级命名空间(如System.String),其直接父命名空间是System,但如果类型在全局命名空间,就会返回空。目标类型是嵌套类型
如果Type参数是嵌套类型(如OuterType.InnerType),typedata.ContainingSymbol指向外层类型,但typedata.ContainingNamespace仍指向外层类型所在的命名空间。若外层类型在全局命名空间,ContainingNamespace.Name同样会返回空。
正确获取完整命名空间的方法
不要直接依赖ContainingNamespace.Name,可以通过以下两种方式获取完整命名空间路径:
方法1:递归拼接命名空间层级
string GetFullNamespace(INamespaceSymbol ns) { if (ns.IsGlobalNamespace) return string.Empty; var parentNamespace = GetFullNamespace(ns.ContainingNamespace); return string.IsNullOrEmpty(parentNamespace) ? ns.Name : $"{parentNamespace}.{ns.Name}"; } // 使用示例 var fullNamespace = GetFullNamespace(typedata.ContainingNamespace);
方法2:利用Roslyn符号格式化
var fullNamespace = typedata.ContainingNamespace.ToDisplayString( SymbolDisplayFormat.FullyQualifiedFormat .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted) );
额外注意事项
你的代码中存在一个潜在笔误:筛选特性时的x => AttributeClass.Name == "MyCustomAttribute"应改为x => x.AttributeClass.Name == "MyCustomAttribute",否则会因上下文变量错误导致获取到不正确的特性数据。
内容的提问来源于stack exchange,提问作者Stuart Grassie

