Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# base()和this()构造函数的最佳实践_C#_Oop_Inheritance_Constructor_Instantiation - Fatal编程技术网

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

C# base()和this()构造函数的最佳实践,c#,oop,inheritance,constructor,instantiation,C#,Oop,Inheritance,Constructor,Instantiation,在什么条件下,我应该使:base()和:this()构造函数在我的构造函数的括号后调用(甚至在代码的其他地方)。这些呼叫何时是良好实践,何时是强制性的 查找“C#中的构造函数链接”。基本上,它看起来是这样的: MyClass():base() //default constructor calling superclass constructor { } MyClass(int arg):this() //non-basic constructor calling base constru

在什么条件下,我应该使
:base()
:this()
构造函数在我的构造函数的括号后调用(甚至在代码的其他地方)。这些呼叫何时是良好实践,何时是强制性的

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

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

MyClass(int arg):this()  //non-basic constructor calling base constructor
{
    //extra initialization
}
它有助于消除构造函数中的代码重复-将它们分为基本部分和特定部分。

:base(…)

如果省略对基构造函数的调用,它将自动调用默认的基构造函数

如果没有默认构造函数,则必须显式调用基构造函数

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);
    }
}
即使存在默认构造函数,您也可能希望调用与默认构造函数不同的构造函数。在这种情况下,您可能仍然希望使用
base(foo,bar)
调用与基本构造函数不同的构造函数

<>我不认为当你想调用基类默认构造函数时省略 BASE()/CUT>是不好的做法,尽管如果你喜欢显式的话,我也不认为包含它是有害的。这是品味的问题

:此(…)

此语法允许您使用不同的签名调用同一类中的另一个构造函数。这从来不是强制性的,但有时是有用的

它何时有用的一个例子是重用构造函数中的公共代码。例如,在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,现在可以使用可选参数,从而减少了对这种方法的需要

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

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

在base:()和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);
    }
}
当基类没有默认构造函数(不带参数的构造函数)时,必须调用基类构造函数。我不知道有哪种情况: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

}

首先,当他们是强制性的

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

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

什么时候是最佳实践?每当你想调用一个不同的构造函数

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);
    }
}
假设您在我前面的示例中向派生的构造函数添加内容

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

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

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

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);
    }
}
基本上,在构造函数的头中使用base和this是为了保留代码,使其更易于维护,更不冗长

这里有一个毫无意义的例子,但我认为它说明了如何使用这两种方法

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.

对不起,我的意思模棱两可。。。我知道这些电话在做什么。我只是不清楚什么时候我应该或者必须打这些电话。如果我不这样做,那么要么我马上就注定要失败,要么会有潜在的bug,要么代码质量很差。我最近非常头痛,因此我想澄清这些情况谢谢“构造函数链接”是我不记得的术语。因此,上一个示例中的调用顺序是:
base(7)
,然后是
Derived(7)
,然后是
Derived()
。换句话说,
this(7)
部分本身不会触发
base()。对吗?对,;构造函数始终是链接的,每个类都调用其基类的构造函数。使用
this
您可以重用这个类的其他构造函数(它本身将使用
base
,或者隐式地不带参数,或者显式地);使用
base
可以选择调用哪个基类构造函数。