我们是否总是在类中包含一个默认的构造函数?
我有一位同事问过这个问题,我们是否应该在一个类中总是包含一个默认构造函数? 如果是这样,为什么? 如果不是,为什么不呢?
例
public class Foo { Foo() { } Foo(int x, int y) { ... } }
我也有兴趣从专家那里得到一些灯。
你必须记住,如果你不提供一个重载的构造函数,编译器会为你生成一个默认的构造函数。 这意味着,如果你有
public class Foo { }
编译器会将其生成为:
public class Foo { public Foo() { } }
但是,只要添加其他构造函数
public class Foo { public Foo(int x, int y) { // ... } }
编译器将不再自动为您生成默认构造函数。 如果这个类已经在其他依赖于默认构造函数的代码中使用了,那么Foo f = new Foo();
那代码现在会破坏
如果你不希望某人能够在不提供数据的情况下初始化这个类,那么你应该创build一个默认的构造函数,这个默认的构造函数将明确地表明你正在阻止没有input数据的情况下构造实例。
但是,有时候需要提供一个默认的构造函数(无论是公共的还是私人的)。 如前所述,某些types的序列化需要默认的构造函数。 有时候一个类有多个参数化的构造函数,但是也需要“低级别”的初始化,在这种情况下,可以使用从参数化的构造函数中链接的私有默认构造函数。
public class Foo { private Foo() { // do some low level initialization here } public Foo(int x, int y) : this() { // ... } public Foo(int x, int y, int z) : this() { // ... } }
有些东西(如序列化)需要一个默认的构造函数。 但是,除此之外,只有在有意义的情况下才应该添加默认的构造函数。
例如,如果Foo.X
和Foo.Y
属性在构造之后是不可变的,那么默认的构造函数并不合理。 即使是用于“空”Foo,静态Empty
访问者也会更容易被发现。
我会说不,绝对不总是 。 假设你有一个只有一些只读字段的类,它们必须被初始化为某个值,并且没有合理的默认值(或者你不想有)。 在这种情况下,我不认为无参数的构造函数是有意义的。
有一个默认的构造函数只是一个好主意,如果有这样一个对象是有道理的。
如果你从这样的构造函数中产生一个不是有效状态的对象,那么它唯一能做的就是引入一个错误。
一般来说,在大多数情况下,最好编写Default构造函数。
通常如果你不指定任何构造函数,.NET会自动为你创build一个默认的构造函数。
序列化需要默认的构造函数。
作为一个方面说明,当使用struct而不是class时,请注意, 没有办法将默认构造函数放出,也无法自己定义它,因此,无论您定义了哪个构造函数,都要确保默认构造函数struct(当所有variables都被设置为默认状态(对于值types通常为0,对于引用types为null)不会破坏结构的实现。
在大多数情况下,默认的构造函数是一个好主意。 但是既然你用了“永远”这个词,那么所需要的只是一个反例。 如果你看看框架,你会发现很多。 例如,System.Web.HttpContext。
如果一个genericstypes有一个默认的构造函数,那么它只能用C#方式实例化(没有reflection)。 另外, new()
generics约束必须被指定:
void Construct<T>() where T : new() { var t = new T(); ... }
调用此方法使用types作为通用types参数没有默认构造函数导致编译器错误。