Skip to content

术语分册 4:特性与泛型

这一册负责解释“特性参数怎么读、泛型约束怎么恢复、嵌套类型怎么回拼”。

AttributeData

  • 一句话说明:表示一次“某个特性被应用到某个目标上”的语义数据
  • 什么时候会用到:你要读取特性参数时
  • 对应教程:第 6 章第 12 章

关键成员:

成员能拿到什么
AttributeClass这个特性本身的类型
ConstructorArguments特性位置参数
NamedArguments特性命名参数
ApplicationSyntaxReference这个特性在源码里的位置

AttributeClass

  • 一句话说明:AttributeData 对应的特性类型
  • 什么时候会用到:你要确认命中的到底是哪一个特性

ConstructorArguments

  • 一句话说明:读取特性位置参数
  • 什么时候会用到:例如 [MyAttr("x", 123)]

你能拿到什么:

你想知道什么看什么
第一个位置参数值ConstructorArguments[0].Value
参数类型ConstructorArguments[i].Type

NamedArguments

  • 一句话说明:读取特性命名参数
  • 什么时候会用到:例如 [MyAttr(Flag = true)]

你能拿到什么:

你想知道什么看什么
某个参数名是否存在遍历 NamedArguments
某个参数值kv.Value.Value

ITypeParameterSymbol

  • 一句话说明:表示泛型类型参数
  • 什么时候会用到:你要恢复 TTKeyTValue 以及它们的约束
  • 对应教程:第 10 章第 11 章

关键成员:

成员能拿到什么
Name泛型参数名
HasReferenceTypeConstraint是否有 class 约束
HasValueTypeConstraint是否有 struct 约束
HasNotNullConstraint是否有 notnull 约束
HasConstructorConstraint是否有 new() 约束
ConstraintTypes其他基类或接口约束

TypeParameters

  • 一句话说明:类型定义上的泛型参数集合
  • 什么时候会用到:你要从 INamedTypeSymbol 取回所有泛型参数

ContainingType

  • 一句话说明:当前类型的外层类型
  • 什么时候会用到:你要恢复嵌套类的外层结构
  • 对应教程:第 10 章

典型用途:

csharp
for (var current = symbol.ContainingType; current is not null; current = current.ContainingType)
{
    // 逐层恢复外层类型
}

最常见的恢复动作

你想恢复什么常见对象
[Attr("x", Flag = true)] 的参数AttributeData
where T : class, new()ITypeParameterSymbol
Outer.Inner<T> 里的 OuterContainingType

这一册最容易漏掉的点

  • 主案例没有特性参数,不代表生成器拿不到特性参数
  • TypeParameters 只给你参数本身,约束还要看每个 ITypeParameterSymbol
  • 嵌套类如果只记类名不记 ContainingType,生成代码很容易错位

下一步去哪里

基于当前仓库文档副本构建的 VitePress 站点