C#源生成器中如何读取LogMemberAttribute的FieldType属性值
问题解决
1. 读取LogMemberAttribute的FieldType值的正确实现
核心原因:Source Generator运行在编译阶段,Roslyn语义API返回的所有类型信息都是ITypeSymbol类型实例,不存在运行时的System.Type对象,所以你强转as Type必然返回null。你拿到的valAsObj本质就是ITypeSymbol,直接转该类型即可使用。
另外你代码里有个笔误:获取keyAttribute时写的是LogWrapper.LogKeyAttribute,但实际定义的Attribute名称是LogKeysAttribute,少了后缀s,这也是你之前无法匹配到Attribute符号的原因之一,需要先修正。
修正后的核心逻辑代码如下:
if (attrib != default) { var fieldTypeArg = attrib.NamedArguments.FirstOrDefault(x => x.Key == "FieldType"); if (fieldTypeArg.Value.Value is ITypeSymbol fieldTypeSymbol) { // 可通过SpecialType枚举判断原生类型,也可以直接取Name属性 string parameterTypeString = fieldTypeSymbol.SpecialType switch { SpecialType.System_Int32 => "int?", SpecialType.System_String => "string", SpecialType.System_Boolean => "bool?", SpecialType.System_Double => "double?", _ => "string" // 未匹配到的类型默认用string }; // 后续直接使用parameterTypeString生成方法参数即可 } }
2. SemanticModel相关问题解答
SemanticModel的定义,以及和语法树的区别
- 语法树:仅描述代码的语法结构,只校验代码写法是否符合语法规范,不关心代码里符号的实际含义。比如代码里写了
int a,语法树只会识别这是变量声明,类型节点文本为int、变量名为a,但不知道int对应System.Int32,也不知道变量a是否在其他位置有定义。 - SemanticModel:是语法树和编译上下文结合的产物,描述代码的语义含义,可以拿到代码中每个符号的完整信息,比如
int对应的类型符号、变量a的作用域、Attribute对应的实际类型、表达式的返回值类型等,是代码分析、生成阶段读取语义信息的核心入口。
SemanticModel的查看方式
没有直接的可视化工具可以像查看语法树一样展示完整的SemanticModel。你可以在Source Generator运行时断点调试,查看各个Symbol、Attribute的属性值,或者在调试时调用ToDisplayString()方法输出符号的字符串表示,验证信息是否符合预期。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

