【问题标题】:There is no argument given that corresponds to the required formal parameter 'firstName' of 'Person.Person(string, string)' [duplicate]没有给出与“Person.Person(string, string)”所需的形式参数“firstName”相对应的参数 [重复]
【发布时间】:2020-04-18 01:21:04
【问题描述】:

好的,所以我有两个简单的类,Person 和 Employee。

人:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}

员工:

public class Employee : Person
{
    public string DepartmentName { get; set; }
}

简单吧?员工继承人,但有问题。员工类给我一个错误,说必须调用父类的构造函数。现在一个类似问题的答案说我应该调用基类的构造函数,它会解决问题。它的作用。

我的问题是,当员工类本身没有自己的构造函数时,我为什么要调用基类的构造函数?

书名 MCSD Certification 70-483 说:

这个系统的一个奇怪之处是你可以创建一个 Employee 类 没有构造函数,即使它允许程序创建一个 Employee 类的实例而不调用 Person 类 构造函数。这意味着 Employee 的以下定义 类是合法的:

public class Employee : Person
{
 public string DepartmentName { get; set; }
}

我的情况和这本书上写的完全一样。这本书说,如果孩子没有自己的,继承并且不调用基类的构造函数是合法的。为什么我仍然收到此错误?即使我有相同的实现。

这本 2018 年的书是否已过时/有错误?难道我做错了什么?还是 C# 中的新更新不允许子类不调用父类的构造函数?

【问题讨论】:

  • 示例中的基类是否也有一个空的构造函数?比如:public Person() : this(string.empty, string.empty) { }
  • @Jimi 不,没有。
  • 书错了。创建派生类的对象时,首先调用基类的构造函数,然后调用派生类的构造函数。如果没有构造函数,则会自动创建一个无参数的构造函数。如果定义了一个构造函数,那么你就不会得到一个自动无参数的构造函数。
  • 所以在显示的代码中,Employee 有一个无参数的构造函数,但 Person 没有。从语义上讲,一个人必须有一个名字,一个员工就是一个人,因此一个员工必须有一个名字。
  • 是的,这是一个错误,我已确认。 @iakobski

标签: c# oop inheritance constructor default-constructor


【解决方案1】:

看起来这是一个错字。因为继承中的每个派生类型的构造函数都应该隐式或显式调用基构造函数。

这样的构造函数:

public Employee () {}

是隐含的:

public Employee () : base() {}

但是,Person 没有无参数构造函数,所以这是一个错误的原因:

CS7036 没有给出与所需参数对应的参数 'Person.Person(string, string)'的形参'firstName'

可以做的是使用默认值创建构造函数:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName = null, string lastName = null)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}

那么Employee 没有构造函数的类将符合条件:

public class Employee : Person
{
     public string DepartmentName { get; set; }
}

【讨论】:

  • 是的,这是一个错误,从他们的网站确认。接受您的回答,因为您正在写作。这是一个错字。
【解决方案2】:

我同意从 MCSD 认证书中了解更多背景信息可能会有所帮助。

实际上,您要创建一个没有名字和姓氏的Employee。但是EmployeePerson,您必须提供名字和姓氏才能构造Person

在您的情况下,Employee 可能没有必要成为Person 的子类。对于Employee 的实例,您是否使用FirstNameLastName

【讨论】:

  • 这本书说如果我不调用它的构造函数,Person 的名字和姓氏等字段将设置为 null,但我无法测试它,因为即使我的员工类也给出了错误。
  • 只有当Person 类有一个将字段设置为空(或将它们保留为默认值)的构造函数时,这才是正确的。如果没有这样的构造函数,创建Person 的唯一方法是使用两个参数调用构造函数。创建对象时不能“不调用构造函数”,new 就是这样做的。如果你没有在派生类中显式调用基类构造函数,你仍然是隐式调用具有匹配参数的基类构造函数。
  • 无论好的设计多么好,我认为这个问题更多的是关于 C# 的工作原理,所以这不是严格的答案。
  • @GrayCat 感谢您的反馈!我刚刚开始参与社区活动。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
  • 2016-05-13
  • 1970-01-01
相关资源
最近更新 更多