C# 什么';允许私有常量用作公共方法的默认参数背后的想法是什么?

C# 什么';允许私有常量用作公共方法的默认参数背后的想法是什么?,c#,.net,default-parameters,C#,.net,Default Parameters,令我惊讶的是,这一个编译并运行: class Program { static void Main() { DoSomething(); } private const int DefaultValue = 2; // <-- Here, private. public static void DoSomething(int value = DefaultValue) { Console.WriteLine

令我惊讶的是,这一个编译并运行:

class Program
{
    static void Main()
    {
        DoSomething();
    }

    private const int DefaultValue = 2; // <-- Here, private.

    public static void DoSomething(int value = DefaultValue)
    {
        Console.WriteLine(value);
    }
}

因此,如果在库中使用私有常量作为默认参数,库的用户仍会看到默认参数。

使用常量时,编译器会用实际值替换所有出现的变量,因此您的代码与此相同:

public static void DoSomething(int value = 2)
这个“概念”背后的想法是什么

其思想是as
const
值是静态的,永远不会更改-您可以将其用作方法可选参数的默认值,就像您可以使用正常值一样。引自:

每个可选参数都有一个默认值作为其定义的一部分。如果没有为该参数发送参数,则使用默认值。默认值必须是以下表达式类型之一:

  • 恒定的表达式

  • 形式为new ValType()的表达式,其中ValType是一个值 类型,例如枚举或结构

  • 默认形式的表达式(ValType),其中ValType是一个值 类型


我(直到今天)的理解是,公开的东西只能是 如果所有其他“引用”元素也是公共的,则使用此选项


从技术上讲,这是正确的。但是在您的场景中,两个成员都是可访问的,因为它们是在同一个类中定义的,但是在我们的例子中,
const
应该在类
Program
之外定义,在类
Program

内部是不可访问的,常量变量在编译时被替换,因此它们在生成的程序集中永远不存在。因此,使用常量的代码实际上与直接使用常量值完全相同。好处是您可以在其他地方重用常量,只需在一个位置更改它


现在,由于常量总是在编译时被替换,所以使它们成为公共或私有的效果也很简单:它只影响其他类型在编译时可以访问它的内容。因此,如果您只想将私有常量保持为当前类型,那么使用私有常量可能会有所帮助,而公共常量可以在整个应用程序中使用。

名称
DefaultValue
是私有的,但数字
2
仍然是数字
2

由于
DefaultValue
是私有的,我们无法从
程序
外部访问
程序.DefaultValue
。想必我们不会特别想这么做

因为我们已经费心定义了
DefaultValue
,这大概是我们在研究
程序如何工作时所关心的事情

因此,当我们为
DoSomething
定义一个默认值时,可能有某种逻辑原因导致我们想要的值恰好与值
DefaultValue
相同

因此,能够在那里使用常数可能是有益的,原因与我们发现常数在任何地方都是有益的差不多

既然
DefaultValue
只是一个
程序
特定的方式来表达
2
,我们没有真正的理由不能这么做

当然,元数据会将其反映为
2
而不是(对外部来说毫无意义)
DefaultValue
,但是如果
const
public
(关于默认值的元数据只给出值,而不管它是否与任何定义的常量相关)

所以没有任何负面影响

因此,考虑到:

  • 实施者有一个优势
  • 对用户来说,仅仅使用文字
    2
    并没有什么不利之处
  • 要防止这种情况发生,必须引入一个特殊规则,作为定义的常量可以在文本中的常量值的任何位置使用的规则的例外

  • 为什么不呢?

    当然@Fajan的答案确实回答了你的问题,变量是常量这一事实并不重要……它是常量仍然很重要,因为你只能将常量值用作默认参数值。我没有测试过它,但如果在库中进行测试,我可能看不到这是默认参数?!?您会看到它是一个默认参数,但只是默认参数是
    2
    ,而不是与
    DefaultValue
    相关。即使
    DefaultValue
    public
    ,该值也会保持不变。生成的CIL具有
    .param[1]=int32(2)
    ,对字段进行引用是无效的CIL,这是其他代码可见
    DefaultValue
    的方式(程序集包含
    .field公共静态文本int32 DefaultValue=int32(2)
    但是任何使用它的编译都将编译为
    2
    而不是
    ldfld
    指令)。我看到了,并尝试了它。非常感谢你的帮助!非常感谢你的回答!谢谢你的回复!尝试在代码中加入
    DefaultValue
    的其他用法(或者实际上是
    public const
    ),您将看到编译后的代码中也会有一个
    2
    ,而不是对
    DefaultValue
    的引用。
    public static void DoSomething(int value = 2)