base() and this() constructors best practices

2019-01-10 05:44发布

Under what conditions am I supposed to make the :base() and :this() constructor calls following my constructor's parentheses (or even in other places in the code). When are these calls good practices and when are they mandatory?

5条回答
贼婆χ
2楼-- · 2019-01-10 06:19

Use base when there is inheritance, and a parent class already provides the functionality that you're trying to achieve.

Use this when you want to reference the current entity (or self), use it in the constructor's header/signature when you don't want to duplicate functionality that is already defined in another constructor.

Basically, using base and this in a constructor's header is to keep your code DRY, making it more maintainable and less verbose

Here's an absolutely meaningless example, but I think it illustrates the idea of showing how the two can be used.

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.");
    }
}

Usage:

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楼-- · 2019-01-10 06:36

You use :base() when you want the constructor of the base class to be automatically called as first instruction of your constructor. :this() it's similar, but it call another constructor on the same class.

In base:() and this(): you can pass as parameters constant values , or expression based on parameters of you constructor.

It's mandatory to call the base constructor when the base class has no default constructor (one that takes no parameters). I don't know of a case in which :this() is mandatory.

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

}
查看更多
smile是对你的礼貌
4楼-- · 2019-01-10 06:37

: base(...)

If you omit the call to a base constructor it will call the default base constructor automatically.

It is mandatory to call a base constructor explicitly if there is no default constructor.

Even if there is a default constructor you may still wish to call a different constructor than the default constructor. In this case you may still wish to use base(foo, bar) to call a different constructor than the base constructor.

I do not consider it to be a bad practice to omit base() when you want to call to the base class default constructor, although if you like to be explicit I see no harm in including it. It is a matter of taste.

: this(...)

This syntax allows you to call one constructor with a different signature from another within the same class. It is never mandatory to do this, but can sometimes be useful.

An example of when it can be useful is for reusing common code in the constructors. For example in C# 3.5 or before you may want to simulate optional parameters on a constructor:

Foo(int x, int y)
{
     this.x = x;
     this.y = y;
}

Foo(int x) : this(x, 10) {}  // y defaults to 10

With C# 4.0 optional parameters are now available which reduces the need for this approach.

An alternative way to reuse code in constructors is to factor it out into a static function which is called from each constructor that wishes to use it.

查看更多
Animai°情兽
5楼-- · 2019-01-10 06:37

Look for "constructor chaining in C#". Basically, it looks like this:

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

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

It helps to remove code duplication in constructors - split them into basic and specific parts.

查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-01-10 06:42

First off, when they're mandatory.

When a class Derived is derived from a class Base, and Base does not have a default (parameterless) constructor, Derived must call base() explicitly with parameters.

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) { }
}

When is it good practice? Whenever you want to call a different constructor.

Suppose you add, in my previous example, content to the constructors in 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);
    }
}

You notice the duplication here? It's simpler to call the this() constructor.

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);
    }
}
查看更多
登录 后发表回答