CA1303:请不要将文本作为本地化参数传递
属性 | 值 |
---|---|
规则 ID | CA1303 |
标题 | 请不要将文本作为本地化参数传递 |
类别 | 全球化 |
修复是中断修复还是非中断修复 | 非中断 |
在 .NET 9 中默认启用 | 否 |
原因
某方法将一个字符串字面量作为参数传递给 .NET 构造函数或方法,该字符串应该是可本地化的字符串。
将文本字符串作为值传递给参数或属性,并且存在以下一种或多种情况时,就会引发此警告:
参数的 LocalizableAttribute 特性或属性设置为
true
。文本字符串将传递给 Console.Write 或 Console.WriteLine 方法重载的
string value
或string format
参数。规则 CA1303 配置为使用命名启发式,并且参数或属性名称包含短语
Text
、Message
或Caption
。
默认情况下,此规则会分析整个代码库,但这是可配置的。
规则说明
嵌入在源代码中的字符串字面量难以本地化。
如何解决冲突
若要解决此规则的冲突,请将字符串字面量替换为通过 ResourceManager 类的实例检索到的字符串。
对于不需要本地化字符串的方法,可通过以下方式消除不必要的 CA1303 警告:
- 如果启用了命名启发式选项,请重命名参数或属性。
- 删除参数上的 LocalizableAttribute 特性或属性,或将其设置为
false
([Localizable(false)]
)。
何时禁止显示警告
如果以下任一表述适用,可禁止显示此规则的警告:
- 不会对代码库进行本地化。
- 该字符串不会向最终用户或使用代码库的开发人员公开。
抑制警告
如果只想抑制单个冲突,请将预处理器指令添加到源文件以禁用该规则,然后重新启用该规则。
#pragma warning disable CA1303
// The code that's violating the rule is on this line.
#pragma warning restore CA1303
若要对文件、文件夹或项目禁用该规则,请在配置文件中将其严重性设置为 none
。
[*.{cs,vb}]
dotnet_diagnostic.CA1303.severity = none
有关详细信息,请参阅如何禁止显示代码分析警告。
配置代码以进行分析
使用下面的选项来配置代码库的哪些部分要运行此规则。
可以仅为此规则、为适用的所有规则或为适用的此类别(全球化)中的所有规则配置此选项。 有关详细信息,请参阅代码质量规则配置选项。
排除特定符号
可以从分析中排除特定符号,如类型和方法。 例如,若要指定规则不应针对名为 MyType
的类型中的任何代码运行,请将以下键值对添加到项目中的 .editorconfig 文件:
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType
选项值中允许的符号名称格式(用 |
分隔):
- 仅符号名称(包括具有相应名称的所有符号,不考虑包含的类型或命名空间)。
- 完全限定的名称,使用符号的文档 ID 格式。 每个符号名称都需要带有一个符号类型前缀,例如表示方法的
M:
、表示类型的T:
,以及表示命名空间的N:
。 .ctor
表示构造函数,.cctor
表示静态构造函数。
示例:
选项值 | 总结 |
---|---|
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType |
匹配名为 MyType 的所有符号。 |
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 |
匹配名为 MyType1 或 MyType2 的所有符号。 |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) |
匹配带有指定的完全限定签名的特定方法 MyMethod 。 |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) |
匹配带有各自的完全限定签名的特定方法 MyMethod1 和 MyMethod2 。 |
排除特定类型及其派生类型
可以从分析中排除特定类型及其派生类型。 例如,若要指定规则不应针对名为 MyType
的类型及其派生类型中的任何代码运行,请将以下键值对添加到项目中的 .editorconfig 文件:
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType
选项值中允许的符号名称格式(用 |
分隔):
- 仅类型名称(包括具有相应名称的所有类型,不考虑包含的类型或命名空间)。
- 完全限定的名称,使用符号的文档 ID 格式,前缀为
T:
(可选)。
示例:
选项值 | 总结 |
---|---|
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType |
匹配名为 MyType 的所有类型及其所有派生类型。 |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 |
匹配名为 MyType1 或 MyType2 的所有类型及其所有派生类型。 |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType |
匹配带有给定的完全限定名称的特定类型 MyType 及其所有派生类型。 |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 |
匹配带有各自的完全限定名称的特定类型 MyType1 和 MyType2 及其所有派生类型。 |
使用命名启发式
可配置包含 Text
、Message
或 Caption
的参数或属性名称是否会触发此规则。
dotnet_code_quality.CA1303.use_naming_heuristic = true
示例
下面的示例演示了在其两个参数之一超出范围时写入控制台的方法。 对于 hour
参数检查,文本字符串将传递到 Console.WriteLine
,这与此规则冲突。 对于 minute
参数检查,通过 ResourceManager 检索的字符串将传递到 Console.WriteLine
,这符合规则。
<Assembly: System.Resources.NeutralResourcesLanguageAttribute("en-US")>
Namespace GlobalizationLibrary
Public Class DoNotPassLiterals
Dim stringManager As System.Resources.ResourceManager
Sub New()
stringManager = New System.Resources.ResourceManager(
"en-US", System.Reflection.Assembly.GetExecutingAssembly())
End Sub
Sub TimeMethod(hour As Integer, minute As Integer)
If (hour < 0 Or hour > 23) Then
'CA1303 fires because a literal string
'is passed as the 'value' parameter.
Console.WriteLine("The valid range is 0 - 23.")
End If
If (minute < 0 Or minute > 59) Then
Console.WriteLine(
stringManager.GetString("minuteOutOfRangeMessage",
System.Globalization.CultureInfo.CurrentUICulture))
End If
End Sub
End Class
End Namespace
public class DoNotPassLiterals
{
ResourceManager stringManager;
public DoNotPassLiterals()
{
stringManager = new ResourceManager("en-US", Assembly.GetExecutingAssembly());
}
public void TimeMethod(int hour, int minute)
{
if (hour < 0 || hour > 23)
{
// CA1303 fires because a literal string
// is passed as the 'value' parameter.
Console.WriteLine("The valid range is 0 - 23.");
}
if (minute < 0 || minute > 59)
{
Console.WriteLine(stringManager.GetString(
"minuteOutOfRangeMessage", CultureInfo.CurrentUICulture));
}
}
}