CA1026(所有参数应具有默认值)和扩展方法

问题描述 投票:19回答:3

Premise

使用带有C#可选参数的代码分析(或fxCop)时,您可以获得CA1026的警告。简短的原因1并不是使用默认值来提供所有参数。

下面的声明正确地生成了此警告

public Color GetColor(bool red, bool blue = true, bool green = true)

但是,有一种情况是您无法使用默认值提供所有参数,这就是扩展方法。因此,下面的声明会因为第一个参数而生成警告:

public static bool ValidateRules(this string s, Rules rules = Rules.Default)

编译器不允许您在this参数上指定默认值,因此只有两个解决方案是:

  1. 忽略警告,我不喜欢这样做,因为它会导致不良做法。
  2. 不使用扩展方法,我不喜欢这样做,因为我发现扩展方法使代码更易读。

Questions

  • 以上两个选项是解决这个问题的唯一方法吗?
  • fxCop / Code Analysis在检查中是否不正确?

  1. The long reason
c# extension-methods code-analysis fxcop
3个回答
34
投票

它不会警告您没有所有参数的默认值 - 它会警告您使用可选参数。

我个人会禁用这个特别的警告。小心使用时,我认为可选参数很好。您应该仔细考虑它们,特别是在默认参数值的版本控制方面以及不支持它们的语言方面(包括v4之前的C#),但在许多环境中,缺点确实不是问题 - 您可以结束使用比在整个地方指定重载更简单的代码。


1
投票

您可以根据具体情况禁止警告。


0
投票

我在Jon Skeet的答案中遗漏的一个论点也是关于可维护性:默认值总是用IL(中间语言)中的值填充。如果您使用外部库,这是一个问题。

以下是重现一个简单示例的步骤:

  1. 创建一个控制台应用
  2. 添加一个ClassLibrary项目
  3. 添加以下代码:

Program.cs中

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var obj = new Class1();

            Console.WriteLine(obj.Foo());
            Console.ReadKey();
        }
    }
}

在你的Class1.cs

namespace ClassLibrary1
{
    public class Class1
    {
        public string Foo(string str = "http")
        {
            return str;
        }
    }
}

如果你运行它,你会看到'http',如预期的那样。

  1. 现在将“http”更改为“https”
  2. 仅编译库(甚至可以卸载控制台项目)
  3. 手动将dll从库的bin文件夹复制到控制台应用程序的bin文件夹
  4. 从命令行运行控制台应用程序,而不是从VS中运行!

你仍会看到http!使用ILSpy,您可以看到http在控制台应用程序中是硬编码的。

在这种情况下,如果开发人员认为他是安全的,可以通过将默认值中的“http”替换为“https”来导致安全问题。

因此,如果更新外部库,则始终再次编译代码。或者只是不要使用默认值。

只需创建一个单独的方法:

        public string Foo()
        {
            return Foo("https");
        }

        public string Foo(string str)
        {
            return str;
        }
© www.soinside.com 2019 - 2024. All rights reserved.