如何通过INamedTypeSymbol获取C#类型别名关键字?Roslyn代码生成
在Roslyn源代码生成器中使用C#类型关键字替代全限定类型名
问题描述
我正在编写一个Roslyn源代码生成器,用于根据指定接口的成员生成代码。例如,给定以下接口:
interface IFoo { string Bar { get; set; } }
我希望生成的代码中属性为:
string IFoo.Bar { get; set; }
但目前只能生成:
System.String IFoo.Bar { get; set; }
这段代码可用,但我想知道能否使用string这类语言关键字?已持有代表System.String的INamedTypeSymbol,有没有办法通过它查找对应的关键字?
解决方案
方法一:利用Roslyn的CSharpSyntaxFacts获取关键字
Roslyn内置的CSharpSyntaxFacts可以直接识别预定义类型并返回对应的语言关键字:
using Microsoft.CodeAnalysis.CSharp; // 假设已获取目标类型符号INamedTypeSymbol typeSymbol var syntaxFacts = CSharpSyntaxFacts.Instance; string typeName; if (syntaxFacts.IsPredefinedType(typeSymbol)) { // 将关键字枚举转换为小写字符串(比如KeywordKind.String → "string") typeName = syntaxFacts.GetKeywordKind(typeSymbol).ToString().ToLower(); } else { // 非预定义类型使用简化名称 typeName = typeSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); }
方法二:手动映射预定义类型
如果不想依赖语法事实服务,可以创建预定义类型与关键字的映射字典,直接匹配:
// 在编译上下文(Compilation)中获取各预定义类型符号 var stringType = compilation.GetTypeByMetadataName("System.String"); var intType = compilation.GetTypeByMetadataName("System.Int32"); var boolType = compilation.GetTypeByMetadataName("System.Boolean"); var typeKeywordMap = new Dictionary<INamedTypeSymbol, string> { { stringType, "string" }, { intType, "int" }, { boolType, "bool" }, // 按需添加其他预定义类型:float、double、char、object等 }; string typeName; if (typeKeywordMap.TryGetValue(typeSymbol, out var keyword)) { typeName = keyword; } else { typeName = typeSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); }
注意事项
- 使用
ToDisplayString时,SymbolDisplayFormat可灵活控制类型名称的显示形式,MinimallyQualifiedFormat会输出最短的有效名称,适合大多数场景。 - 确保用于匹配的
INamedTypeSymbol来自当前编译上下文,避免跨编译的符号不匹配问题。
内容的提问来源于stack exchange,提问作者Andrew Cooper
相关产品推荐
相关产品推荐

