You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:16:06