我们真的可以调用无参数构造函数默认构造函数吗

本文关键字:构造函数 参数 默认 调用 真的 我们 | 更新日期: 2024-06-14 09:55:19

我对C#中"默认构造函数"的含义感到非常困惑。很多人,包括我的编程教授,只是把任何无参数构造函数称为"默认构造函数"(就像这里或这里的问答一样)。甚至默认构造函数上的SO标记wiki也说它是"一个无参数的构造函数……经常(注意它说经常,而不是总是)由编译器生成"。

如果要遵循这个逻辑,构造函数是否"默认"取决于你如何调用它。也就是说,如果你可以用"默认"的方式调用它,而不需要任何参数,那么它就是默认构造函数。

但是,如果我读得正确的话,MSDN似乎只为无参数构造函数命名"默认构造函数",该构造函数是在没有指定其他构造函数时隐式生成的,调用无参数基类构造函数,并(像任何其他构造函数一样)将class的字段初始化为其值。

仔细想想,这比"default" == "parameterless"更有意义:当你没有选择任何其他选项时,隐式生成的构造函数有点像默认选项

那么,调用所有无参数构造函数默认构造函数是否正确

或者调用形式为public C(): base() {}(用于常规类)和protected C(): base() {}(用于抽象类)的显式定义构造函数默认构造函数是否正确,因为它们符合MSDN上默认构造函数的描述?

或者这个术语真的只适用于隐式生成的构造函数吗?

还有(可能是最重要的问题):这个词的定义最被广泛接受,是正确的还是不正确的?

我们真的可以调用无参数构造函数默认构造函数吗

不仅仅MSDN使用术语"默认构造函数"专门用于"如果不指定任何其他内容"或"始终,用于结构(C#之前)"或"除非指定自己的无参数构造函数(C#),否则始终,用于结构"提供的构造函数,而是C#语言规范本身。请注意,在结构的情况下,编译器不需要在IL中为您生成一个结构——它已经作为类型系统的一部分存在了。

就我个人而言,我发现这是一个有用的区别,尤其是在专门讨论构造函数语义时。当构造函数不是讨论的重点时,就不那么迂腐了——例如,如果有人在谈论LINQ,并描述了以下代码:

List<int> x = new List<int>();
x.Add(10);
int y = x.First();

比如调用List<T>的默认构造函数,然后添加到它,等等——那么挑剔我们实际上是在调用无参数构造函数是没有意义的。(如果不看源代码,我们甚至无法判断它是否是默认的构造函数——这个概念只在实现中有意义,而不是像以前那样从外部有意义。)

还有一个更细微的区别,即使是规范也会出错(我应该提出一个bug)。考虑一下C#5规范中的这句话:

如果一个类不包含实例构造函数声明,则会自动提供默认的实例构造函数。该默认构造函数只是调用直接基类的无参数构造函数。

事实并非如此。尽管Base没有无参数构造函数,但此代码编译良好

public class Base
{
    public Base(int x = 0)
    {
        Console.WriteLine("Base: x={0}", x);
    }
}
public class Derived : Base
{
}

更准确的说法是,默认构造函数调用基类构造函数,就好像存在对base()的显式调用一样,并进行重载解析等正常过程。

下一篇:

还有(可能是最重要的问题):这个词的定义最被广泛接受,是正确的还是不正确的?

我想说的是,大多数人甚至都没有想过,而是交替使用这两个术语。这不是他们认为定义是这样或那样的问题——我怀疑大多数人都不会想到定义它的想法。(这并不是要贬低他们,只是他们觉得这不是他们需要关心的事情。并不是每个人都想成为一名语言律师。)