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

Beginner to C#: How to do constructor chaining, overriding and using :this / :base?

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

我见过 :base 用于继承,但我不确定如何使用。 我见过 :this 在很多地方都用过,但我总是想不通为什么要用它。

下面是一些带有 :this 的代码示例(为了便于论证,在没有 setters/getters 的情况下制作了 public 个变量)。

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

}}

我只能理解第一个构造函数是如何使用的,例如制作一个 "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;
    }

当然我不确定上面的任何代码是否有意义,但我看到一些 类 的构造函数每个都带有 :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;
    }

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

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

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

在你的例子中,"base"指的是Shape(Color Colour, Point Position),"this"指的是Circle(Color Colour, Point Position, double Radius)。

第一个构造函数正在访问定义中的第二个构造函数,这就是它使用 :this.

的原因

第二个构造函数正在使用基 class 中定义的构造函数,这就是它使用基的原因:

如果您使用以下方法创建 Circle 实例:

Circle()

它会使用第一个构造函数,它会调用第二个构造函数(添加它需要的参数),后者会调用基类中的构造函数 class。

I think :base refers to the parent class, but I'm not sure why and how

base 是访问 parent class.

成员的关键字

1) var p = base.Property; 将从 parent class

访问字段或 属性

2) base.Method(); 将从 parent class

访问一个方法

3) base(..) 将从 parent class

访问构造函数

why is :this being used in the first constructor and not :base?

this 是访问同一 class 成员的关键字。有 3 个参数定义了 Circle 的属性。 CircleShape 仅共享 1 属性: color。因此,默认构造函数调用相同 class Circle 的更专用构造函数(这就是 this() 的原因),第二个构造函数将共享 属性 color 传递给parent待处理。

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

我会尽可能简单地解释它。

构造函数重载

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

构造函数链接

这是通过使用关键字 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; }
}

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

关键词base

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

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

一般来说: this(...)指的是当前class的一个构造函数。在您的示例中,这可用于避免代码重复。我认为给出的示例从逻辑的角度来看没有太大意义,但它是合法的 C# 并且 - 基本上 - 如何使用 : this(...)

第二个示例更符合逻辑 - 或更连贯,因为默认构造函数提供了合理的默认值以传递给参数化构造函数。

这是默认构造函数,它为要传递给参数化构造函数的值创建合理的默认值:

public Circle():this(Color.Black, new Point(0,0), 1)

这是参数化的构造函数,它将基本 class 也需要的参数传递给 Shape 的构造函数:

public Circle(Color Colour, Point Position, double Radius):base(Colour, Position) 

如果你需要一个标准的圆圈,你可以用

创建一个
var shape = new Circle();

另一方面,如果您需要在特定位置创建一个具有特定颜色和特定半径的圆,则可以使用参数化构造函数创建一个

var shape = new Circle(Color.Silver, new Point(1,2), 5);