Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.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# 在C中调用重写构造函数和基构造函数#_C#_Constructor - Fatal编程技术网

C# 在C中调用重写构造函数和基构造函数#

C# 在C中调用重写构造函数和基构造函数#,c#,constructor,C#,Constructor,我有两个类,Foo和Bar,它们的构造函数如下: class Foo { Foo() { // do some stuff } Foo(int arg) { // do some other stuff } } class Bar : Foo { Bar() : base() { // some third thing } } Bar(int arg) : Bar(), base(a

我有两个类,Foo和Bar,它们的构造函数如下:

class Foo
{
    Foo()
    {
      // do some stuff
    }

    Foo(int arg)
    {
      // do some other stuff
    }
}

class Bar : Foo
{
    Bar() : base()
    {
      // some third thing
    }
}
Bar(int arg) : Bar(), base(arg)
{
  // some fourth thing
}
现在我想为Bar引入一个构造函数,它接受一个int,但是我想让Bar()中发生的东西和Foo(int)中的东西一样运行。大概是这样的:

class Foo
{
    Foo()
    {
      // do some stuff
    }

    Foo(int arg)
    {
      // do some other stuff
    }
}

class Bar : Foo
{
    Bar() : base()
    {
      // some third thing
    }
}
Bar(int arg) : Bar(), base(arg)
{
  // some fourth thing
}

在C#中有什么方法可以做到这一点吗?到目前为止,我最好的方法是将Bar()完成的工作放入一个函数中,该函数也会被Bar(int)调用,但这非常不雅观。

你不能让接受int的Bar构造函数调用无参数构造函数吗?

不,这是不可能的。如果您使用Reflector检查为每个构造函数生成的IL,您将看到原因——最终会为基类调用两个构造函数。理论上,编译器可以构造隐藏的方法来完成您想要的任务,但是与您显式地执行相同的任务相比,这并没有任何优势。

您可以将Bar()中的内容放入Bar(int)中,并使用带有默认值的Bar()调用Bar(int)?然后Bar(int)可以调用基本构造函数

class Bar : Foo
{
    Bar() : this(0)
    {
    }

    Bar(int arg) : base(arg)
    {
    }
}

这并不能完全回答您的问题,但取决于您的场景,这可能是一个可行的解决方案。

我将重新链接构造函数,因此它们被称为

Bar() : this(0) 
Bar(int) : Foo(int) initializes Bar
Foo(int) initializes Foo
Foo() : this(0) 

如果无参数构造函数为其他构造函数的int参数假定某种默认值,则这是合适的。如果构造函数是不相关的,那么您的类型可能有问题,或者我们需要更多关于您试图实现什么的信息。

这是我唯一能想到的

 public class Foo
{
    public Foo()
    {
    }
    public Foo(int? arg): this()
    {
    }

}
public class Bar : Foo
{
    private int x;
    public Bar(): this(new int?()) // edited to fix type ambiguity
    {
        // stuff that only runs for paramerless ctor
    }
    public Bar(int? arg)
        : base(arg)
    {
        if (arg.HasValue)
        {
            // Do stuff for both parameterless and parameterized ctor
        }
        // Do other stuff for only parameterized ctor
    }
}

我建议您将构造器链从最不特定改为最特定

class Foo
{
    Foo()
    {
      // do some stuff
    }

    Foo(int arg): this()
    {
      // do some other stuff
    }
}

class Bar : Foo
{
    Bar() : Bar(0)
    {
      // some third thing
    }

    Bar(int arg): base(arg)
    {
      // something
    }
}

Bar对象的任何创建现在都将调用所有4个构造函数。构造函数链接应该为更具体的构造函数提供默认值,而不是相反。你应该认真考虑你想要完成的事情,并确保你所做的是有意义的。Curt是对的,有技术上的原因你不能这样做,但也有逻辑上的原因你不能这样做。

你能把Bar()的初始化代码变成一个方法并从两个构造函数调用它,让新的构造函数只调用base(arg)吗?

你可以使用以下代码:

public Foo
{
    public Foo()
    {
        this.InitializeObject();
    }

    public Foo(int arg) : this()
    {
        // do something with Foo's arg
    }

    protected virtual void InitializeObject()
    {
        // initialize object Foo
    }
}

public Bar : Foo
{
    public Bar : base() { }

    public Bar(int arg) : base(arg)
    {
       // do something with Bar's arg
    }

    protected override void InitializeObject()
    {
       // initialize object Bar

       base.InitializeObject();
    }
}
只需像上面的代码一样重写
InitializeObject()
方法,并将所有要放入无参数构造函数的代码放在那里。最后在代码末尾调用
base.InitializeObject()


希望这是有用的。

他还想调用基类的参数化构造函数。可以为null的想法有+1,但它有一些流程-如果添加另一个带有一个参数(类类型,而不是struct)的ctor,它将失败,就像现在这样(null)将不知道选择哪一个。可能是因为您没有给出问题的解决方案,即使问题显然存在。值得注意的是,虽然构造函数可以编写
只读
字段,但
InitializeObject
方法将无法直接这样做。要在
InitializeObject
方法中初始化此类字段,必须让构造函数将其作为
ref
out
参数传递(我更喜欢
ref
,因为构造对象时字段值定义为空,而且我不喜欢虚拟方法上的
out
参数,因为其他语言中的重写可能会将它们视为
ref
参数)。您可以对只读字段执行此操作:
专用只读字符串\u ro1=“只读1”;private readonly string _-ro2;private readonly int _-ro3;public Bar():base(){}public Bar(int-arg):base(arg){u-ro3=arg;_-ro2=“只读:”+arg;}
基本上,如果只读字段的值是由构造函数参数确定的,则可以将字段的初始化放在构造函数上。如果不是,则可以像上面的第一个只读字段一样进行初始化(\u ro1)。您的答案是建议将初始化代码从构造函数移到虚拟方法。可以在构造函数或字段初始值设定项中初始化只读字段,但也可以使用虚拟方法进行初始化,前提是将有问题的字段作为
ref
out
参数传递给有问题的方法。顺便说一句,一个我很想在vb.net和C#中看到,这是一种定义字段或伪字段的方法,该字段或伪字段将使用构造函数参数中的值进行初始化,并可在以后的字段初始化程序中使用其中
(整数大小)
初始化
ArrSize
将表明此类型的任何构造函数都将有一个名为
Size
int
参数,或者链接到一个名为
Size
的参数,并且传递给该参数的值应用于初始化
ArrSize
。在我看来,如果一个字段将被设置为一个可以e是基于构造函数参数计算的,以后再也没有修改过,将声明和初始化结合起来比在不同的地方写入更干净。