base()和this()构造函数的最佳实践

时间:2010-09-26 11:15:02

标签: c# oop inheritance constructor instantiation

在什么条件下我应该按照构造函数的括号(甚至在代码中的其他位置)调用:base():this()构造函数。这些什么时候称为良好做法,什么时候强制执行?

5 个答案:

答案 0 :(得分:97)

<强> : 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可选参数现在可用,这减少了对这种方法的需求。

在构造函数中重用代码的另一种方法是将其分解为静态函数,该函数从希望使用它的每个构造函数调用。

答案 1 :(得分:31)

首先,当他们是强制性的时候。

如果某个班级Derived来自某个班级Base,且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);
    }
}

答案 2 :(得分:27)

当存在继承时使用base,并且父类已经提供了您尝试实现的功能。

当您想要引用当前实体(或self)时使用this,当您不想复制已在另一个构造函数中定义的功能时,请在构造函数的头/签名中使用它。

基本上,使用base并在构造函数的标题中保留代码DRY,使其更易于维护且更简洁

这是一个绝对没有意义的例子,但我认为它说明了如何使用这两个的想法。

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.

答案 3 :(得分:8)

查找“C#中的构造函数链接”。基本上,它看起来像这样:

MyClass():base()  //default constructor calling superclass constructor
{
}

MyClass(int arg):this()  //non-basic constructor calling base constructor
{
    //extra initialization
}

它有助于删除构造函数中的代码重复 - 将它们拆分为基本和特定部分。

答案 4 :(得分:4)

如果希望将基类的构造函数自动调用为构造函数的第一条指令,则使用:base()。 :this()它类似,但它在同一个类上调用另一个构造函数。

在base :()和this()中:你可以传递参数常量值,或者基于构造函数的参数传递表达式。

当基类没有默认构造函数(不带参数的构造函数)时,必须调用基础构造函数。我不知道一个案例: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

}