CA2241:为格式化方法提供正确的参数

属性
规则 ID CA2241
标题 为格式化方法提供正确的参数
类别 使用情况
修复是中断修复还是非中断修复 非中断
在 .NET 8 中默认启用 作为建议

原因

传递到 WriteLineWriteSystem.String.Format 等方法的 format 字符串参数不包含与每个对象参数相对应的格式项,反之亦然。

默认情况下,此规则仅分析对之前提到的三种方法的调用,但这是可配置的。

规则说明

WriteLineWriteFormat 等方法的参数由格式字符串后跟若干个 System.Object 实例构成。 格式字符串由文本和嵌入的格式项组成,其形式为 {index[,alignment][:formatString]}。 “index”是一个从零开始的整数,用于指示要格式化的对象。 如果对象在格式字符串中没有相应的索引,则忽略该对象。 如果“index”指定的对象不存在,则会在运行时引发 System.FormatException

如何解决冲突

若要解决与此规则的冲突,请为每个对象参数提供一个格式项,并为每个格式项提供一个对象参数。

何时禁止显示警告

不禁止显示此规则发出的警告。

配置代码以进行分析

使用以下选项来配置针对其运行此规则的其他方法。

其他字符串格式设置方法

可以配置应由此规则分析的其他字符串格式设置方法的名称。 例如,若要将名为 MyFormat 的所有方法指定为字符串格式设置方法,可将以下键值对添加到项目的 .editorconfig 文件中:

dotnet_code_quality.CA2241.additional_string_formatting_methods = MyFormat

选项值中允许的方法名称格式(用 | 分隔):

  • 仅方法名称(包括具有相应名称的所有方法,不考虑包含类型或命名空间)
  • 完全限定的名称,使用符号的文档 ID 格式,前缀为 M:(可选)。

示例:

选项值 总结
dotnet_code_quality.CA2241.additional_string_formatting_methods = MyFormat 匹配编译中所有名为 MyFormat 的方法。
dotnet_code_quality.CA2241.additional_string_formatting_methods = MyFormat1|MyFormat2 匹配编译中所有名为 MyFormat1MyFormat2 的方法。
dotnet_code_quality.CA2241.additional_string_formatting_methods = NS.MyType.MyFormat(ParamType) 将特定方法 MyFormat 与给定的完全限定签名相匹配。
dotnet_code_quality.CA2241.additional_string_formatting_methods = NS1.MyType1.MyFormat1(ParamType)|NS2.MyType2.MyFormat2(ParamType) 将特定方法 MyFormat1MyFormat2 与相应的完全限定签名相匹配。

自动确定其他字符串格式设置方法

可以配置分析器来自动尝试确定字符串格式设置方法,而不是指定其他字符串格式设置方法的显式列表。 默认情况下禁用此选项。 如果启用该选项,则任何具有 string format 参数后跟 params object[] 参数的方法都会被视作字符串格式设置方法:

dotnet_code_quality.CA2241.try_determine_additional_string_formatting_methods_automatically = true

示例

下面的示例显示了两个规则冲突。

Imports System

Namespace ca2241

    Class CallsStringFormat

        Sub CallFormat()

            Dim file As String = "file name"
            Dim errors As Integer = 13

            ' Violates the rule.
            Console.WriteLine(String.Format("{0}", file, errors))

            Console.WriteLine(String.Format("{0}: {1}", file, errors))

            ' Violates the rule and generates a FormatException at runtime.
            Console.WriteLine(String.Format("{0}: {1}, {2}", file, errors))

        End Sub

    End Class

End Namespace
class CallsStringFormat
{
    void CallFormat()
    {
        string file = "file name";
        int errors = 13;

        // Violates the rule.
        Console.WriteLine(string.Format("{0}", file, errors));

        Console.WriteLine(string.Format("{0}: {1}", file, errors));

        // Violates the rule and generates a FormatException at runtime.
        Console.WriteLine(string.Format("{0}: {1}, {2}", file, errors));
    }
}