CA1304:指定 CultureInfo

属性
规则 ID CA1304
标题 指定 CultureInfo
类别 全球化
修复是中断修复还是非中断修复 非中断
在 .NET 8 中默认启用

原因

某方法或构造函数调用的成员有接受 System.Globalization.CultureInfo 参数的重载,但该方法或构造函数没有调用接受 CultureInfo 参数的重载。 此规则将忽略对以下方法的调用:

还可以配置此规则将排除的多个符号。

规则说明

如果未提供 CultureInfoSystem.IFormatProvider 对象,则重载成员提供的默认值可能不会在所有区域设置中产生你想要的效果。 此外,.NET 成员根据可能不适合你的代码的假设选择默认区域性和格式。 为了确保代码满足相应的情况,你应该根据以下准则提供区域性特定的信息:

  • 如果将向用户显示值,请使用当前区域性。 请参阅 CultureInfo.CurrentCulture

  • 如果通过软件存储和访问值(即保留到文件或数据库),请使用固定区域性。 请参阅 CultureInfo.InvariantCulture

  • 如果不知道该值的目的地,请让数据使用者或提供商指定区域性。

即使重载成员的默认行为适合你的需求,但最好还是显式调用区域性特定的重载,以便你的代码自我记录,且更容易维护。

注意

CultureInfo.CurrentUICulture 仅用于通过使用 System.Resources.ResourceManager 类的实例检索本地化的资源。

如何解决冲突

若要解决此规则的冲突,请使用接受 CultureInfo 参数的重载。

何时禁止显示警告

当确定默认区域性是正确的选择,并且代码可维护性不是重要的开发优先级时,可禁止显示此规则的警告。

抑制警告

如果只想抑制单个冲突,请将预处理器指令添加到源文件以禁用该规则,然后重新启用该规则。

#pragma warning disable CA1304
// The code that's violating the rule is on this line.
#pragma warning restore CA1304

若要对文件、文件夹或项目禁用该规则,请在配置文件中将其严重性设置为 none

[*.{cs,vb}]
dotnet_diagnostic.CA1304.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 匹配名为 MyType1MyType2 的所有符号。
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) 匹配带有各自的完全限定签名的特定方法 MyMethod1MyMethod2

排除特定类型及其派生类型

可以从分析中排除特定类型及其派生类型。 例如,若要指定规则不应针对名为 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 匹配名为 MyType1MyType2 的所有类型及其所有派生类型。
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 匹配带有各自的完全限定名称的特定类型 MyType1MyType2 及其所有派生类型。

演示如何解决冲突的示例

在下面的示例中,BadMethod 将导致此规则出现两个冲突。 GoodMethod 通过将固定区域性传递给 String.Compare 来更正第一个冲突,通过将当前区域性传递给 String.ToLower 来更正第二个冲突,因为向用户显示了 string3

public class CultureInfoTest
{
    public void BadMethod(String string1, String string2, String string3)
    {
        if (string.Compare(string1, string2, false) == 0)
        {
            Console.WriteLine(string3.ToLower());
        }
    }

    public void GoodMethod(String string1, String string2, String string3)
    {
        if (string.Compare(string1, string2, false,
                          CultureInfo.InvariantCulture) == 0)
        {
            Console.WriteLine(string3.ToLower(CultureInfo.CurrentCulture));
        }
    }
}

演示格式化输出的示例

下面的示例演示了当前区域性对 DateTime 类型选择的默认 IFormatProvider 的影响。

public class IFormatProviderTest
{
    public static void Main1304()
    {
        string dt = "6/4/1900 12:15:12";

        // The default behavior of DateTime.Parse is to use
        // the current culture.

        // Violates rule: SpecifyIFormatProvider.
        DateTime myDateTime = DateTime.Parse(dt);
        Console.WriteLine(myDateTime);

        // Change the current culture to the French culture,
        // and parsing the same string yields a different value.

        Thread.CurrentThread.CurrentCulture = new CultureInfo("Fr-fr", true);
        myDateTime = DateTime.Parse(dt);

        Console.WriteLine(myDateTime);
    }
}

该示例产生下面的输出:

6/4/1900 12:15:12 PM
06/04/1900 12:15:12

另请参阅