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

发布于 2024-09-11 03:26:56 字数 891 浏览 11 评论 0原文

前提

当使用具有 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)

编译器不会让您在该参数上指定默认值,因此唯一的两个解决方案是:

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

问题

  • 以上两个选项是唯一的吗 有办法解决这个问题吗?
  • 是 fxCop/代码 检查中的分析不正确?

  1. 长原因

Premise

When using code analysis (or fxCop) with C# optional parameters you can get a warning of CA1026. The short reason1 for this is not suppling all parameters with a default value.

The declaration below rightly generates this warning

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

However there is a situation where you could not supply all parameters with a default, and that is extension methods. So the declaration below generates the warning because of the first parameter:

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

The compiler will not let you specify a default value on the this parameter so the only two solutions is to:

  1. Ignore the warning, which I do not like doing because it leads to bad practices.
  2. Not use extension methods, which I do not like doing because I find extension methods make the code more readible.

Questions

  • Are the above two options the only
    way to solve this?
  • Is fxCop/Code
    Analysis incorrect in it's check?

  1. The long reason

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不忘初心 2024-09-18 03:26:56

它并不是警告您没有所有参数的默认值,而是警告您根本使用可选参数。

我个人会禁用这个特定的警告。当小心使用时,我认为可选参数是可以的。您应该仔细考虑它们,尤其是默认参数值的版本控制,以及不支持它们的语言(包括 v4 之前的 C#),但在许多环境中,缺点实际上并不存在一个问题 - 与在各处指定重载相比,您最终可以得到更简单的代码。

It's not warning you for not having defaults for all parameters - it's warning you for using optional parameters at all.

Personally I would disable this particular warning. When used with care, I think optional parameters are fine. You should think carefully about them particularly in terms of versioning of the default parameter value and in terms of languages which don't support them (including C# before v4) but in many environments the downsides really aren't an issue - and you can end up with much simpler code than by specifying overloads all over the place.

爺獨霸怡葒院 2024-09-18 03:26:56

我在 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;
        }

An argument that I am missing in Jon Skeet's answer is also about maintainability: Default values are always filled in with it's value in the IL (intermediate language). This is an issue if you're using external libraries.

Here are steps to reproduce a simple example:

  1. Create a console app
  2. Add a ClassLibrary project to it
  3. Add the following code:

Program.cs

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

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

and in your Class1.cs

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

If you run it you will see 'http', as expected.

  1. Now change "http" to "https"
  2. Compile only the library (maybe even unload the console project)
  3. Copy the dll from the library's bin folder to the console app's bin folder by hand
  4. Run the console app from the command line, not from within VS!

You will still see http! With ILSpy you can see that http is hardcoded in the console app.

In this case this could lead to a security issue if the developer thinks he is safe by replacing the "http" to "https" in the default value.

So if external libraries are updated always compile your code again. Or just don't use default values.

Just create a separate method:

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

        public string Foo(string str)
        {
            return str;
        }
十级心震 2024-09-18 03:26:56

您可以根据具体情况抑制警告。

You can suppress the warning on a case-by-case basis.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文