base()和this()构造函数的最佳实践
在什么条件下,我应该做:base()
和:this()
构造函数调用遵循我的构造函数的括号(甚至在代码中的其他地方)。 什么时候这些被称为良好做法,什么时候是强制性的?
: base(...)
如果您省略了对基础构造函数的调用,它将自动调用默认的基础构造函数。
如果没有默认构造函数,则必须显式调用基础构造函数。
即使有一个默认的构造函数,你可能仍然希望调用与默认的构造函数不同的构造函数。 在这种情况下,您可能仍希望使用base(foo, bar)
来调用与基础构造函数不同的构造函数。
我不认为当你想调用基类的默认构造函数时,省略base()
是不好的做法,但是如果你喜欢明确的话,我认为在包含它的时候没有什么坏处。 这是一个品味的问题。
: this(...)
这个语法允许你在同一个类中调用一个具有不同签名的构造函数。 这样做绝不是强制性的,但有时可能有用。
例如什么时候可以使用的是在构造函数中重用公共代码。 例如在C#3.5中,或者您可能想要在构造函数上模拟可选参数之前:
Foo(int x, int y) { this.x = x; this.y = y; } Foo(int x) : this(x, 10) {} // y defaults to 10
使用C#4.0可选参数现在可用,这减less了这种方法的需要。
在构造函数中重用代码的另一种方法是将其分解成一个静态函数,该函数从每个希望使用它的构造函数中调用。
首先,当他们是强制性的。
当Derived
类是从Base
类Derived
,而Base
没有默认的(无参数)构造函数时, Derived
必须使用参数显式调用base()
。
public class Base { public Base(int i) { } } public class Derived : Base { // public Derived() { } wouldn't work - what should be given for i? public Derived() : base(7) { } public Derived(int i) : base(i) { } }
什么时候是好习惯? 每当你想调用不同的构造函数。
假设我在前面的例子中添加了Derived中的构造函数的内容。
public class Derived : Base { // public Derived() { } wouldn't work - what should be given for i? public Derived() : base(7) { Console.WriteLine("The value is " + 7); } public Derived(int i) : base(i) { Console.WriteLine("The value is " + i); } }
你注意到这里的重复? 调用this()构造函数更简单。
public class Derived : Base { // public Derived() { } wouldn't work - what should be given for i? public Derived() : this(7) { } public Derived(int i) : base(i) { Console.WriteLine("The value is " + i); } }
有inheritance时使用base
,并且父类已经提供了您尝试实现的function。
当你想引用当前的实体(或者自己)的时候使用它,当你不想复制已经在另一个构造函数中定义的function时,在构造函数的头文件/签名中使用它。
基本上, 使用基地,这在一个构造函数的头是让你的代码干 ,使其更容易维护,而不是冗长
这是一个毫无意义的例子,但我认为这说明了如何使用这两个概念。
class Person { public Person(string name) { Debug.WriteLine("My name is " + name); } } class Employee : Person { public Employee(string name, string job) : base(name) { Debug.WriteLine("I " + job + " for money."); } public Employee() : this("Jeff", "write code") { Debug.WriteLine("I like cake."); } }
用法:
var foo = new Person("ANaimi"); // output: // My name is ANaimi var bar = new Employee("ANaimi", "cook food"); // output: // My name is ANaimi // I cook food for money. var baz = new Employee(); // output: // My name is Jeff // I write code for money. // I like cake.
当你希望基类的构造函数被自动调用为构造函数的第一条指令时,你可以使用:base()。 :this()它是相似的,但它调用同一个类上的另一个构造函数。
在base :()和this()中:你可以传递参数的常量值,或者基于你的构造函数的参数expression式。
当基类没有默认构造函数(不带参数)时,调用基类构造函数是必须的。 我不知道其中:this()是强制性的。
public class ABaseClass { public ABaseClass(string s) {} } public class Foo : AChildClass { public AChildClass(string s) : base(s) {} //base mandatory public AChildClass() : base("default value") {} //base mandatory public AChildClass(string s,int i) : base(s+i) {} //base mandatory } public class AnotherBaseClass { public ABaseClass(string s) {} public ABaseClass():this("default value") {} //call constructor above } public class Foo : AnotherChildClass { public AnotherChildClass(string s) : base(s) {} //base optional }
寻找“在C#中的构造函数链”。 基本上,它看起来像这样:
MyClass():base() //default constructor calling superclass constructor { } MyClass(int arg):this() //non-basic constructor calling base constructor { //extra initialization }
它有助于删除构造函数中的代码重复 – 将它们分解为基本和特定的部分。