消息格式化
本文档详细介绍诊断消息的格式化和本地化。
文档信息
- 难度级别: 初级
- 预计阅读时间: 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));
}最佳实践
- 使用清晰的语言 - 避免技术术语
- 提供具体信息 - 包含相关的名称、类型等
- 使用参数占位符 - 提高灵活性
- 处理复数形式 - 根据语言选择合适的方式
- 保持消息简洁 - 不要过长
- 提供建议 - 告诉用户如何修复
- 使用一致的格式 - 所有消息使用相同的风格
- 测试消息显示 - 确保消息在 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: 不需要,中文不区分单复数形式。