C# 初学者:如何进行构造函数链接、重写和使用 :this / :base?

Moh*_*iya 1 c# inheritance constructor overloading chaining

我去年学习了 Java,我认为在编写构造函数方面没有遇到过问题。不幸的是,我对 C# 中的重载和链接如何工作,甚至它的基本概念感到非常困惑。

我见过 :base 在继承中使用,但我不确定如何使用。我见过:这在很多地方都被使用,而且它总是让我困惑为什么要使用它。

下面是一些带有 :this 的代码的示例(为了论证,没有 setter/getter 的情况下创建了公共变量)。

public class Person
{
    public string firstName;
    public string lastName;
    public string height;
    public int age;
    public string colour;

public Person():this("George", "Seville", "45cm", 10, "Black")
    {
    // This is the default constructor, and we're defining the default 
values.
     }

public Person(string firstName, string lastName, string height, int age, 
string colour)
    {
        this.firstName = firstName;
        this.lastName = lastName;
        this.height = height;
        this.age = age;
        this.colour = colour;
    }

}}
Run Code Online (Sandbox Code Playgroud)

我只能理解如何使用第一个构造函数,例如创建一个简单的“Person”对象会给它默认值。据我所知。该代码尚未完成,因为它显示了 2 个默认构造函数。我希望能够对每个可用的变体进行重载和链接,即 1 个参数、2 个参数……这样它们都会适当地重载和链接。

所以它应该看起来像这样(可能不正确):

public Person():this("George", "Seville", "45cm", 10, "Black")
    {
    // This is the default constructor, and we're defining the default 
values.
     }

public Person(string firstName):this(firstName, "George", "Seville", "45cm", 
10, Black)
    {
        this.firstName = firstName;
    }

public Person(string firstName, string lastName):this(firstName, lastName, 
"Seville", "45cm", 10, Black)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }
Run Code Online (Sandbox Code Playgroud)

当然,我不确定上面的任何代码是否有意义,但我已经看到一些带有构造函数的类,每个类都带有 :this ,每个构造函数都链接到它下面的一个,直到用户可以使用以下命令创建一个对象定义的参数的任意组合。

至于 :base,这让我完全困惑。这是我在网上实际找到的一个例子:

    public class Circle:Shape
{
    public Circle():this(Color.Black, new Point(0,0), 1)
    {
    }

    public Circle(Color Colour, Point Position, double Radius):base(Colour, 
Position) 
    {
        this.Radius = Radius;
    }
Run Code Online (Sandbox Code Playgroud)

我认为 :base 指的是父类,但我不确定为什么以及如何。另外,为什么在第一个构造函数中使用 :this 而不是 :base ?

有两个方面我很困惑。使用 :this 和 :base 并准确理解构造函数链接和重载的工作原理。如果我的问题太抽象,请告诉我。我已尝试尽可能具体。

非常感谢大家的支持和时间。非常感激!

Zoh*_*led 6

我将尝试尽可能简单地解释它。

构造函数重载

这里没有什么新内容,就像重载任何其他方法一样 - 您只需要相同的名称但不同的签名(意味着传递到构造函数的不同参数)。

构造函数链接

这是通过使用关键字来完成的this- 就像您问题中的代码示例一样。
顺便说一句,我通常使用它从最复杂的构造函数到最简单的构造函数。
示例代码:

public class Person
{
    public Person()
    {
        Children = new List<Person>();
    }

    public Person(string firstName)
        : this()
    {
        this.FirstName = firstName;
    }

    public Person(string firstName, string lastName)
        : this(firstName)
    {
        this.LastName = lastName;
    }

    public string FirstName { get; }
    public string LastName { get; }
    public IEnumerable<Person> Children { get; }
}
Run Code Online (Sandbox Code Playgroud)

当然,通过使用构造函数链为属性设置默认值是一种有效的设计,我自己在需要时也使用过它,但通常情况并非如此。

关键词base

该关键字始终指基(或父)类。当重写方法和属性时,您也会经常看到它。
当谈到构造函数时 - 您的假设是正确的 - 它确实指的是基(或父)类。因此,当在构造函数中使用时(例如在 Circle 示例中),您可以控制派生(或子)类构造函数将执行的基构造函数的重载。
因此,例如,如果您的基类包含三个构造函数,您可以选择要调用其中之一。

除非另有说明,c# 会将派生类的构造函数链接到基类的默认构造函数。
请注意,如果您从没有默认(即:无参数)构造函数的类继承,则必须: base(...)在构造函数中指定 ,即使您的基类只有一个构造函数(因为这是传递所需参数的唯一方法)到它)。