Skip to content

正确性反模式

识别和避免源生成器中的逻辑错误。


📋 文档信息

属性
难度高级
阅读时间25 分钟
前置知识符号系统、语义模型
相关文档反模式索引符号比较

反模式 1: 错误的符号比较

❌ 错误做法

csharp
public bool IsSameType(ITypeSymbol type1, ITypeSymbol type2)
{
    // 使用 == 比较符号是错误的
    return type1 == type2;
}

✅ 正确做法

csharp
public bool IsSameType(ITypeSymbol type1, ITypeSymbol type2)
{
    // 使用 SymbolEqualityComparer 比较符号
    return SymbolEqualityComparer.Default.Equals(type1, type2);
}

反模式 2: 忽略编译诊断

❌ 错误做法

csharp
public void GenerateCode(Compilation compilation)
{
    // 不检查编译错误就生成代码
    var code = GenerateCodeFromCompilation(compilation);
    context.AddSource("Generated.g.cs", code);
}

✅ 正确做法

csharp
public void GenerateCode(Compilation compilation)
{
    // 检查编译错误
    var diagnostics = compilation.GetDiagnostics();
    if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
    {
        // 有错误,不生成代码
        return;
    }
    
    var code = GenerateCodeFromCompilation(compilation);
    context.AddSource("Generated.g.cs", code);
}

反模式 3: 不检查 null 值

❌ 错误做法

csharp
public void ProcessSymbol(ISymbol symbol)
{
    // 不检查 null 就使用
    var name = symbol.Name;
    var type = ((ILocalSymbol)symbol).Type;
}

✅ 正确做法

csharp
public void ProcessSymbol(ISymbol symbol)
{
    if (symbol == null)
    {
        return;
    }
    
    var name = symbol.Name;
    
    if (symbol is ILocalSymbol local && local.Type != null)
    {
        var type = local.Type;
        // 处理...
    }
}

反模式 4: 类型检查不完整

❌ 错误做法

csharp
public void ProcessType(ITypeSymbol type)
{
    // 只处理类,忽略其他类型
    if (type.TypeKind == TypeKind.Class)
    {
        // 处理类...
    }
    // 结构、接口等被忽略
}

✅ 正确做法

csharp
public void ProcessType(ITypeSymbol type)
{
    switch (type.TypeKind)
    {
        case TypeKind.Class:
            // 处理类
            break;
        case TypeKind.Struct:
            // 处理结构
            break;
        case TypeKind.Interface:
            // 处理接口
            break;
        default:
            // 处理其他类型或报告不支持
            break;
    }
}

关键要点

  • ✅ 使用 SymbolEqualityComparer 比较符号
  • ✅ 检查编译诊断
  • ✅ 始终检查 null 值
  • ✅ 处理所有可能的类型情况

相关文档


最后更新: 2026-02-06

基于 MIT 许可发布