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

时间:2010-07-20 16:01:40

标签: c# extension-methods code-analysis fxcop

前提

将代码分析(或fxCop)与C#可选参数一起使用时,您可以收到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. 不使用我不喜欢的扩展方法,因为我发现扩展方法使代码更易读。
  3. 问题

    • 上述两个选项是否唯一 解决这个问题的方法?
    • 是fxCop / Code 分析不正确吗?

    1. The long reason

3 个答案:

答案 0 :(得分:34)

它没有警告您没有所有参数的默认值 - 它警告您在所有中使用可选参数

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

答案 1 :(得分:1)

您可以根据具体情况取消警告。

答案 2 :(得分: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;
        }