符号类型详解
📚 文档导航
本文档详细介绍各种符号类型及其使用方法。
📖 文档系列
| 文档 | 内容 | 难度 |
|---|---|---|
| 符号系统基础 | 基础概念、符号层次、快速入门 | 🟢 入门 |
| 符号类型详解 ⭐ | INamedTypeSymbol、IMethodSymbol、IPropertySymbol 等 | 🟡 中级 |
| 符号操作 | 获取、遍历、查询、比较符号 | 🟡 中级 |
| 高级主题 | 继承、接口、特性、显示格式、文档注释 | 🔴 高级 |
| 最佳实践 | 性能优化、实战场景、设计模式 | 🟡 中级 |
符号类型关系图
INamedTypeSymbol 详解
INamedTypeSymbol 表示命名类型:类、结构、接口、枚举、委托。
基本属性
csharp
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
public class NamedTypeSymbolExamples
{
public void DemonstrateNamedTypeSymbol()
{
var code = @"
namespace MyApp
{
public abstract class Animal
{
public string Name { get; set; }
public abstract void MakeSound();
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine(""Woof!"");
}
}
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var compilation = CreateCompilation(tree);
var model = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();
var dogClass = root.DescendantNodes()
.OfType<ClassDeclarationSyntax>()
.First(c => c.Identifier.Text == "Dog");
var typeSymbol = model.GetDeclaredSymbol(dogClass) as INamedTypeSymbol;
// 基本信息
Console.WriteLine($"名称: {typeSymbol.Name}");
Console.WriteLine($"完整名称: {typeSymbol.ToDisplayString()}");
Console.WriteLine($"元数据名称: {typeSymbol.MetadataName}");
// 类型种类
Console.WriteLine($"类型种类: {typeSymbol.TypeKind}");
// 输出: TypeKind.Class
// 访问修饰符
Console.WriteLine($"访问级别: {typeSymbol.DeclaredAccessibility}");
// 输出: Accessibility.Public
// 修饰符
Console.WriteLine($"是抽象: {typeSymbol.IsAbstract}");
Console.WriteLine($"是密封: {typeSymbol.IsSealed}");
Console.WriteLine($"是静态: {typeSymbol.IsStatic}");
Console.WriteLine($"是值类型: {typeSymbol.IsValueType}");
Console.WriteLine($"是引用类型: {typeSymbol.IsReferenceType}");
// 继承关系
Console.WriteLine($"基类: {typeSymbol.BaseType?.ToDisplayString()}");
// 输出: MyApp.Animal
Console.WriteLine($"接口:");
foreach (var iface in typeSymbol.Interfaces)
{
Console.WriteLine($" - {iface.ToDisplayString()}");
}
// 成员
Console.WriteLine($"成员数量: {typeSymbol.GetMembers().Length}");
Console.WriteLine($"方法数量: {typeSymbol.GetMembers().OfType<IMethodSymbol>().Count()}");
Console.WriteLine($"属性数量: {typeSymbol.GetMembers().OfType<IPropertySymbol>().Count()}");
}
private Compilation CreateCompilation(SyntaxTree tree)
{
return CSharpCompilation.Create("temp")
.AddReferences(
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Console).Assembly.Location)
)
.AddSyntaxTrees(tree);
}
}泛型类型
csharp
public class GenericTypeExamples
{
public void AnalyzeGenericType()
{
var code = @"
public class Container<T> where T : class
{
public T Value { get; set; }
}
public class Usage
{
public void Test()
{
var container = new Container<string>();
}
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var compilation = CreateCompilation(tree);
var model = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();
// 分析泛型类定义
var containerClass = root.DescendantNodes()
.OfType<ClassDeclarationSyntax>()
.First(c => c.Identifier.Text == "Container");
var typeSymbol = model.GetDeclaredSymbol(containerClass) as INamedTypeSymbol;
Console.WriteLine($"是泛型: {typeSymbol.IsGenericType}");
Console.WriteLine($"类型参数数量: {typeSymbol.TypeParameters.Length}");
foreach (var typeParam in typeSymbol.TypeParameters)
{
Console.WriteLine($"类型参数: {typeParam.Name}");
Console.WriteLine($" 有引用类型约束: {typeParam.HasReferenceTypeConstraint}");
Console.WriteLine($" 有值类型约束: {typeParam.HasValueTypeConstraint}");
Console.WriteLine($" 有构造函数约束: {typeParam.HasConstructorConstraint}");
}
// 分析泛型类型使用
var objectCreation = root.DescendantNodes()
.OfType<ObjectCreationExpressionSyntax>()
.First();
var createdType = model.GetTypeInfo(objectCreation).Type as INamedTypeSymbol;
Console.WriteLine($"\n构造的泛型类型: {createdType.ToDisplayString()}");
Console.WriteLine($"原始定义: {createdType.OriginalDefinition.ToDisplayString()}");
Console.WriteLine($"类型参数:");
foreach (var typeArg in createdType.TypeArguments)
{
Console.WriteLine($" - {typeArg.ToDisplayString()}");
}
}
private Compilation CreateCompilation(SyntaxTree tree)
{
return CSharpCompilation.Create("temp")
.AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
.AddSyntaxTrees(tree);
}
}IMethodSymbol 详解
IMethodSymbol 表示方法、构造函数、析构函数等。
基本属性
csharp
public class MethodSymbolExamples
{
public void DemonstrateMethodSymbol()
{
var code = @"
public class Calculator
{
public async Task<int> AddAsync(int a, int b)
{
await Task.Delay(100);
return a + b;
}
public static void Log(string message)
{
Console.WriteLine(message);
}
public virtual void Process() { }
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var compilation = CreateCompilation(tree);
var model = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();
var addMethod = root.DescendantNodes()
.OfType<MethodDeclarationSyntax>()
.First(m => m.Identifier.Text == "AddAsync");
var methodSymbol = model.GetDeclaredSymbol(addMethod) as IMethodSymbol;
// 基本信息
Console.WriteLine($"方法名: {methodSymbol.Name}");
Console.WriteLine($"完整签名: {methodSymbol.ToDisplayString()}");
// 返回类型
Console.WriteLine($"返回类型: {methodSymbol.ReturnType.ToDisplayString()}");
// 参数
Console.WriteLine($"参数数量: {methodSymbol.Parameters.Length}");
foreach (var param in methodSymbol.Parameters)
{
Console.WriteLine($" - {param.Type.ToDisplayString()} {param.Name}");
}
// 修饰符
Console.WriteLine($"是异步: {methodSymbol.IsAsync}");
Console.WriteLine($"是静态: {methodSymbol.IsStatic}");
Console.WriteLine($"是虚方法: {methodSymbol.IsVirtual}");
Console.WriteLine($"是重写: {methodSymbol.IsOverride}");
Console.WriteLine($"是抽象: {methodSymbol.IsAbstract}");
Console.WriteLine($"是密封: {methodSymbol.IsSealed}");
Console.WriteLine($"是扩展方法: {methodSymbol.IsExtensionMethod}");
// 方法种类
Console.WriteLine($"方法种类: {methodSymbol.MethodKind}");
// MethodKind.Ordinary, Constructor, Destructor, etc.
}
private Compilation CreateCompilation(SyntaxTree tree)
{
return CSharpCompilation.Create("temp")
.AddReferences(
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Console).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Task).Assembly.Location)
)
.AddSyntaxTrees(tree);
}
}泛型方法
csharp
public class GenericMethodExamples
{
public void AnalyzeGenericMethod()
{
var code = @"
public class Utils
{
public T Clone<T>(T source) where T : ICloneable
{
return (T)source.Clone();
}
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var compilation = CreateCompilation(tree);
var model = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();
var method = root.DescendantNodes()
.OfType<MethodDeclarationSyntax>()
.First();
var methodSymbol = model.GetDeclaredSymbol(method) as IMethodSymbol;
Console.WriteLine($"是泛型方法: {methodSymbol.IsGenericMethod}");
Console.WriteLine($"类型参数数量: {methodSymbol.TypeParameters.Length}");
foreach (var typeParam in methodSymbol.TypeParameters)
{
Console.WriteLine($"类型参数: {typeParam.Name}");
Console.WriteLine($" 约束:");
foreach (var constraint in typeParam.ConstraintTypes)
{
Console.WriteLine($" - {constraint.ToDisplayString()}");
}
}
}
private Compilation CreateCompilation(SyntaxTree tree)
{
return CSharpCompilation.Create("temp")
.AddReferences(
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(ICloneable).Assembly.Location)
)
.AddSyntaxTrees(tree);
}
}IPropertySymbol 详解
IPropertySymbol 表示属性和索引器。
基本属性
csharp
public class PropertySymbolExamples
{
public void DemonstratePropertySymbol()
{
var code = @"
public class Person
{
// 自动属性
public string Name { get; set; }
// 只读属性
public int Age { get; }
// 带逻辑的属性
private string _email;
public string Email
{
get => _email;
set => _email = value?.ToLower();
}
// 表达式体属性
public string FullInfo => $""{Name}, {Age}"";
// 索引器
public string this[int index]
{
get => index.ToString();
set { }
}
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var compilation = CreateCompilation(tree);
var model = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();
var classDecl = root.DescendantNodes()
.OfType<ClassDeclarationSyntax>()
.First();
var typeSymbol = model.GetDeclaredSymbol(classDecl) as INamedTypeSymbol;
foreach (var property in typeSymbol.GetMembers().OfType<IPropertySymbol>())
{
Console.WriteLine($"属性: {property.Name}");
Console.WriteLine($" 类型: {property.Type.ToDisplayString()}");
Console.WriteLine($" 访问级别: {property.DeclaredAccessibility}");
// 访问器
Console.WriteLine($" 有 getter: {property.GetMethod != null}");
Console.WriteLine($" 有 setter: {property.SetMethod != null}");
if (property.GetMethod != null)
{
Console.WriteLine($" getter 访问级别: {property.GetMethod.DeclaredAccessibility}");
}
if (property.SetMethod != null)
{
Console.WriteLine($" setter 访问级别: {property.SetMethod.DeclaredAccessibility}");
}
// 特殊属性
Console.WriteLine($" 是索引器: {property.IsIndexer}");
Console.WriteLine($" 是只读: {property.IsReadOnly}");
Console.WriteLine($" 是只写: {property.IsWriteOnly}");
Console.WriteLine($" 是静态: {property.IsStatic}");
Console.WriteLine($" 是虚属性: {property.IsVirtual}");
Console.WriteLine($" 是重写: {property.IsOverride}");
Console.WriteLine();
}
}
private Compilation CreateCompilation(SyntaxTree tree)
{
return CSharpCompilation.Create("temp")
.AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
.AddSyntaxTrees(tree);
}
}IFieldSymbol 详解
IFieldSymbol 表示字段。
基本属性
csharp
public class FieldSymbolExamples
{
public void DemonstrateFieldSymbol()
{
var code = @"
public class Constants
{
public const int MaxValue = 100;
public static readonly string AppName = ""MyApp"";
private int _count;
public readonly DateTime CreatedAt;
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var compilation = CreateCompilation(tree);
var model = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();
var classDecl = root.DescendantNodes()
.OfType<ClassDeclarationSyntax>()
.First();
var typeSymbol = model.GetDeclaredSymbol(classDecl) as INamedTypeSymbol;
foreach (var field in typeSymbol.GetMembers().OfType<IFieldSymbol>())
{
Console.WriteLine($"字段: {field.Name}");
Console.WriteLine($" 类型: {field.Type.ToDisplayString()}");
Console.WriteLine($" 访问级别: {field.DeclaredAccessibility}");
Console.WriteLine($" 是常量: {field.IsConst}");
Console.WriteLine($" 是只读: {field.IsReadOnly}");
Console.WriteLine($" 是静态: {field.IsStatic}");
Console.WriteLine($" 是 volatile: {field.IsVolatile}");
if (field.IsConst && field.HasConstantValue)
{
Console.WriteLine($" 常量值: {field.ConstantValue}");
}
Console.WriteLine();
}
}
private Compilation CreateCompilation(SyntaxTree tree)
{
return CSharpCompilation.Create("temp")
.AddReferences(
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(DateTime).Assembly.Location)
)
.AddSyntaxTrees(tree);
}
}IParameterSymbol 详解
IParameterSymbol 表示方法参数。
基本属性
csharp
public class ParameterSymbolExamples
{
public void DemonstrateParameterSymbol()
{
var code = @"
public class Example
{
public void Method(
int required,
string optional = ""default"",
params int[] numbers)
{
}
public void RefMethod(
ref int refParam,
out int outParam,
in int inParam)
{
outParam = 0;
}
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var compilation = CreateCompilation(tree);
var model = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();
var methods = root.DescendantNodes()
.OfType<MethodDeclarationSyntax>();
foreach (var method in methods)
{
var methodSymbol = model.GetDeclaredSymbol(method) as IMethodSymbol;
Console.WriteLine($"方法: {methodSymbol.Name}");
foreach (var param in methodSymbol.Parameters)
{
Console.WriteLine($" 参数: {param.Name}");
Console.WriteLine($" 类型: {param.Type.ToDisplayString()}");
Console.WriteLine($" 位置: {param.Ordinal}");
Console.WriteLine($" 是可选: {param.IsOptional}");
Console.WriteLine($" 是 params: {param.IsParams}");
Console.WriteLine($" 是 this: {param.IsThis}");
// 引用类型
switch (param.RefKind)
{
case RefKind.None:
Console.WriteLine($" 传递方式: 值传递");
break;
case RefKind.Ref:
Console.WriteLine($" 传递方式: ref");
break;
case RefKind.Out:
Console.WriteLine($" 传递方式: out");
break;
case RefKind.In:
Console.WriteLine($" 传递方式: in");
break;
}
// 默认值
if (param.HasExplicitDefaultValue)
{
Console.WriteLine($" 默认值: {param.ExplicitDefaultValue ?? "null"}");
}
Console.WriteLine();
}
}
}
private Compilation CreateCompilation(SyntaxTree tree)
{
return CSharpCompilation.Create("temp")
.AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
.AddSyntaxTrees(tree);
}
}INamespaceSymbol 详解
INamespaceSymbol 表示命名空间。
基本属性
csharp
public class NamespaceSymbolExamples
{
public void DemonstrateNamespaceSymbol(Compilation compilation)
{
// 获取全局命名空间
var globalNamespace = compilation.GlobalNamespace;
Console.WriteLine("全局命名空间成员:");
ExploreNamespace(globalNamespace, 0);
}
private void ExploreNamespace(INamespaceSymbol ns, int depth)
{
var indent = new string(' ', depth * 2);
// 获取子命名空间
foreach (var childNs in ns.GetNamespaceMembers())
{
Console.WriteLine($"{indent}命名空间: {childNs.Name}");
Console.WriteLine($"{indent} 完整名称: {childNs.ToDisplayString()}");
Console.WriteLine($"{indent} 是全局: {childNs.IsGlobalNamespace}");
ExploreNamespace(childNs, depth + 1);
}
// 获取类型成员
foreach (var type in ns.GetTypeMembers())
{
Console.WriteLine($"{indent}类型: {type.Name} ({type.TypeKind})");
}
}
}ILocalSymbol 详解
ILocalSymbol 表示局部变量。
基本属性
csharp
public class LocalSymbolExamples
{
public void DemonstrateLocalSymbol()
{
var code = @"
public class Example
{
public void Method()
{
const int maxValue = 100;
var name = ""John"";
ref int refValue = ref GetValue();
}
private ref int GetValue() => ref _value;
private int _value;
}
";
var tree = CSharpSyntaxTree.ParseText(code);
var compilation = CreateCompilation(tree);
var model = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();
var method = root.DescendantNodes()
.OfType<MethodDeclarationSyntax>()
.First(m => m.Identifier.Text == "Method");
var locals = method.DescendantNodes()
.OfType<VariableDeclaratorSyntax>()
.Select(v => model.GetDeclaredSymbol(v) as ILocalSymbol)
.Where(l => l != null);
foreach (var local in locals)
{
Console.WriteLine($"局部变量: {local.Name}");
Console.WriteLine($" 类型: {local.Type.ToDisplayString()}");
Console.WriteLine($" 是常量: {local.IsConst}");
Console.WriteLine($" 是 ref: {local.IsRef}");
Console.WriteLine($" 是 ref readonly: {local.IsRefReadOnly}");
if (local.IsConst && local.HasConstantValue)
{
Console.WriteLine($" 常量值: {local.ConstantValue}");
}
Console.WriteLine();
}
}
private Compilation CreateCompilation(SyntaxTree tree)
{
return CSharpCompilation.Create("temp")
.AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
.AddSyntaxTrees(tree);
}
}下一步
🔗 相关资源
- 符号系统基础 - 返回主文档
- 语义模型 - 了解如何使用语义模型访问符号
- 符号 API(官方文档)
最后更新: 2025-01-21