Skip to content

消息格式化

本文档详细介绍诊断消息的格式化和本地化。

文档信息

  • 难度级别: 初级
  • 预计阅读时间: 10 分钟

🎯 学习目标

  • ✅ 学会使用参数占位符
  • ✅ 掌握消息格式化技巧
  • ✅ 了解本地化支持

参数替换

使用占位符在消息中插入动态内容:

csharp
public static class MessageFormattingExamples
{
    // 单个参数
    public static readonly DiagnosticDescriptor SingleParam = new DiagnosticDescriptor(
        id: "MSG001",
        title: "单参数消息",
        messageFormat: "类名 '{0}' 不符合规范",
        category: "Naming",
        defaultSeverity: DiagnosticSeverity.Warning,
        isEnabledByDefault: true);
    
    // 多个参数
    public static readonly DiagnosticDescriptor MultipleParams = new DiagnosticDescriptor(
        id: "MSG002",
        title: "多参数消息",
        messageFormat: "方法 '{0}' 的参数 '{1}' 类型应该是 '{2}' 而不是 '{3}'",
        category: "Type",
        defaultSeverity: DiagnosticSeverity.Warning,
        isEnabledByDefault: true);
    
    // 带格式化的参数
    public static readonly DiagnosticDescriptor FormattedParam = new DiagnosticDescriptor(
        id: "MSG003",
        title: "格式化参数",
        messageFormat: "方法复杂度为 {0:N0},超过了阈值 {1:N0}",
        category: "Maintainability",
        defaultSeverity: DiagnosticSeverity.Warning,
        isEnabledByDefault: true);
}

使用示例

csharp
public void UseSingleParameter(
    SyntaxNodeAnalysisContext context,
    string className)
{
    var diagnostic = Diagnostic.Create(
        SingleParam,
        Location.None,
        className);
    
    context.ReportDiagnostic(diagnostic);
}

public void UseMultipleParameters(
    SyntaxNodeAnalysisContext context,
    string methodName,
    string paramName,
    string expectedType,
    string actualType)
{
    var diagnostic = Diagnostic.Create(
        MultipleParams,
        Location.None,
        methodName,
        paramName,
        expectedType,
        actualType);
    
    context.ReportDiagnostic(diagnostic);
}

复数处理

csharp
public void HandlePlural(
    SyntaxNodeAnalysisContext context,
    int count)
{
    // 中文不需要特殊处理复数
    var diagnostic = Diagnostic.Create(
        Rule,
        Location.None,
        count);
    
    context.ReportDiagnostic(diagnostic);
}

相关文档

本地化支持

虽然本文档使用中文,但如果需要支持多语言,可以使用资源文件:

csharp
using System.Resources;

public class LocalizationExamples
{
    private static readonly LocalizableString Title = 
        new LocalizableResourceString(
            nameof(Resources.AnalyzerTitle),
            Resources.ResourceManager,
            typeof(Resources));
    
    private static readonly LocalizableString MessageFormat = 
        new LocalizableResourceString(
            nameof(Resources.AnalyzerMessageFormat),
            Resources.ResourceManager,
            typeof(Resources));
    
    private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
        id: "LOC001",
        title: Title,
        messageFormat: MessageFormat,
        category: "Naming",
        defaultSeverity: DiagnosticSeverity.Warning,
        isEnabledByDefault: true);
}

internal class Resources
{
    private static ResourceManager resourceManager;
    
    internal static ResourceManager ResourceManager
    {
        get
        {
            if (resourceManager == null)
            {
                resourceManager = new ResourceManager(
                    "MyAnalyzer.Resources",
                    typeof(Resources).Assembly);
            }
            return resourceManager;
        }
    }
    
    internal static string AnalyzerTitle =>
        ResourceManager.GetString(nameof(AnalyzerTitle));
    
    internal static string AnalyzerMessageFormat =>
        ResourceManager.GetString(nameof(AnalyzerMessageFormat));
}

最佳实践

  1. 使用清晰的语言 - 避免技术术语
  2. 提供具体信息 - 包含相关的名称、类型等
  3. 使用参数占位符 - 提高灵活性
  4. 处理复数形式 - 根据语言选择合适的方式
  5. 保持消息简洁 - 不要过长
  6. 提供建议 - 告诉用户如何修复
  7. 使用一致的格式 - 所有消息使用相同的风格
  8. 测试消息显示 - 确保消息在 IDE 中正确显示

常见问题

Q: 如何在消息中使用多个参数?

A: 使用多个占位符:

csharp
messageFormat: "方法 '{0}' 的参数 '{1}' 类型应该是 '{2}'"

var diagnostic = Diagnostic.Create(
    Rule,
    location,
    methodName,
    paramName,
    expectedType);

Q: 如何格式化数字?

A: 使用格式化占位符:

csharp
messageFormat: "方法复杂度为 {0:N0},超过了阈值 {1:N0}"

var diagnostic = Diagnostic.Create(
    Rule,
    location,
    complexity,
    threshold);

Q: 中文需要处理复数吗?

A: 不需要,中文不区分单复数形式。

基于 MIT 许可发布