【问题标题】:C# invoke base constructor with parameters and parameterless constructor of current classC#调用带有参数的基构造函数和当前类的无参数构造函数
【发布时间】:2018-06-03 00:32:11
【问题描述】:
public class A
{
    public A() { Console.WriteLine("A parameterless"); }
    public A(int a) : this() { Console.WriteLine("A with a"); }
}

public class B : A
{
    public B() { Console.WriteLine("B paramterless"); }
    public B(int b) : base(b) { Console.WriteLine("B with b"); }
}

public class Program
{
    public static void Main(string[] args)
    {
        new B(3);
    }
}

给予:
无参数
一个有一个
B 与 b

我还能做些什么来调用“B 无参数”?
所以,我需要一些类似的东西:

public B(int b) : base(b), this() { ... }

或者,一个虚拟构造函数,这样当基类调用this()时,它会重定向到子类的无参数构造函数。

【问题讨论】:

  • 你不能。您可以选择 一个 其他构造函数来链接。如果问题不那么抽象,并且我们知道您实际在做什么(除了将调试信息打印到控制台之外),我们可能会有具体的建议来更好地解决问题。
  • 你不能,你只能通过构造函数创建一个直接链,而不是一个构造函数然后返回到另一个构造函数。因此,您可以创建从 B(int) 到 B(),然后到 A() 或 A(int) 的链。如果你想去 B(int)->B()->A(int) 你已经失去了 int 因为 B(int) 中的代码还没有执行。虚拟构造函数不是 C# 语言的一部分。您应该详细说明您要解决的问题,因为可能有其他方法可以解决它。
  • ... 但是有一个解决方法:您可以在 B()B(int b) 中调用私有方法
  • @Fildor 确实如此,但是如果您尝试将值分配给这些方法中不可能的只读字段。同样,我们需要更多有关潜在问题的信息,以便提出好的解决方案。
  • @LasseVågsætherKarlsen 是的,这是一个缺点。这就是 Damien 的评论在 “如果问题不那么抽象并且我们知道您实际在做什么 [...] 我们可能会就如何更好地解决问题提出具体建议”

标签: c# .net inheritance constructor virtual


【解决方案1】:

你不能用构造函数链来做到这一点。但我看不出有什么问题:

public class A
{
    public A()
    {
        Console.WriteLine("A parameterless");
    }
    public A(int a) : this()
    {
        Console.WriteLine("A with a");
    }
}

public class B : A
{
    public B()
    {
        ThingsIWant();
    }
    public B(int b) : base(b)
    {
        ThingsIWant();
        Console.WriteLine("B with b");
    }

    protected void ThingsIWant()
    {
        Console.WriteLine("B paramterless");
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        new B(3);
    }
}

【讨论】:

  • “我看不出有什么问题” - 尝试将值分配给ThingsIWant 中的只读字段...
  • @Fildor 这正是我想要的。然而,“你不能”是这个问题的答案。
  • 是否可以选择只读 Propertyprivate string field; //set in ThingsIWant 然后public string Field { get => field; } ?
  • @Fildor 该字段是私有的,无论如何。这不是一个大问题,我只是想保护自己免于意外更改它。如果它是只读的,它看起来更干净。
【解决方案2】:

我将扩展“不能”的答案并添加“不应该”。多个构造函数重载的用例是接收与对象构造相关的不同输入,通常让接收较少信息的构造函数为提供给另一个构造函数的值提供适当的默认值。从可维护性的角度来看,您通常会将包含最详细参数的重载作为真正构造逻辑存在的唯一位置,并让其他构造函数调用该位置。

【讨论】:

  • 如果我没记错的话,这会导致确切的问题,但反过来。现在无参数构造函数需要使用一些默认参数调用this(x),我必须为每个类重复此操作,这就是代码重复。否则,我需要调用base(),这将无法使用参数调用子构造函数。
  • @MackThax 子类无参数构造函数将调用其自己的更详细的构造函数,从而确保所需的基类构造函数。基类没有调用子类的构造函数。
【解决方案3】:

尝试为 ThingsIWant 中的只读字段赋值

这是语言/编译器的限制:编译器允许您仅在构造函数内物理上更改只读字段,而不是在对象构造期间调用的方法中更改。

一个老的msdn document 说:

“当字段声明包含只读修饰符时,对由声明引入的字段的赋值只能作为声明的一部分或在同一类的构造函数中发生。”

【讨论】:

    猜你喜欢
    • 2011-10-08
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多