Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.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# - Fatal编程技术网

C# 为什么可以';我们在子类的构造函数的函数体中调用基类的构造函数吗?

C# 为什么可以';我们在子类的构造函数的函数体中调用基类的构造函数吗?,c#,C#,为什么我们不能在子类的构造函数的函数体中调用基类的构造函数?比如说, public class Baseclass { public int X; public Baseclass () { } public Baseclass (int x) { this.X = x; } } 为什么 而不是 public class Subclass : Baseclass { public Subclass (int x) : { base(x); } } 或 我的问题更多的是从C语

为什么我们不能在子类的构造函数的函数体中调用基类的构造函数?比如说,

public class Baseclass
{
  public int X;
  public Baseclass () { }
  public Baseclass (int x) { this.X = x; }
}
为什么

而不是

public class Subclass : Baseclass
{
  public Subclass (int x) : { base(x);  }
}

我的问题更多的是从C语言的设计角度出发,或者是其他类似的面向对象语言,如C++和java,它们都是相同的设计。
谢谢。

Java实际上不允许您提出的建议-在Java中,对
super()
的调用在子类构造函数的主体内,如果调用之前有任何语句,则为编译错误:

// This is Java
public class Subclass extends ParentClass {

    public Subclass() {
        String x = "foo";
        super(); // <-- compile error
    }
}
在上面的示例中,
localX
的值是多少

答案是“未定义的”,而C++和CLR(和java)是为了防止未定义的行为而C++是更宽容的,但这并不意味着你应该这样做。 通过要求所有基类在子类之前完全初始化,可以防止与未初始化数据相关的一系列错误

但是,我要说一件事——没有正式的理由说明我们不能在调用父构造函数之前执行静态代码。实际上,我们可以在C#中实现这一点,但我们必须重构代码,使之成为通过父类的构造函数参数进行的静态函数调用,这并不美观,也不允许将数据直接传递回子类构造函数。所以我希望我们能做这样的事情:

public class ParentClass {

    public ParentClass(String x, Int32 y) {
        // ...
    }
}

public class Subclass : ParentClass {

    private static ComplexObject GetComplexObject() {
        // ...
    }

    public Subclass() {
        // All code before `base()` is executed in a static context:
        ComplexObject cmplx = GetComplexObject();
        base( cmplx.X, cmplx.Y );
    }
}
相反,我们目前需要这样做:

public Subclass()
    : base( GetComplexObject().X, GetComplexObject().Y ) {
}
或者使用带有私有构造函数的静态工厂方法:

private Subclass(String x, Int32 y) : base( x, y ) {

}

public static Subclass Create() {

    ComplexObject cmplx = GetComplexObject();
    return new Subclass( cmplx.X, cmplx.Y );
}

Java实际上不允许您提出的建议-在Java中,对
super()
的调用在子类构造函数的主体内,如果调用之前有任何语句,则为编译错误:

// This is Java
public class Subclass extends ParentClass {

    public Subclass() {
        String x = "foo";
        super(); // <-- compile error
    }
}
在上面的示例中,
localX
的值是多少

答案是“未定义的”,而C++和CLR(和java)是为了防止未定义的行为而C++是更宽容的,但这并不意味着你应该这样做。 通过要求所有基类在子类之前完全初始化,可以防止与未初始化数据相关的一系列错误

但是,我要说一件事——没有正式的理由说明我们不能在调用父构造函数之前执行静态代码。实际上,我们可以在C#中实现这一点,但我们必须重构代码,使之成为通过父类的构造函数参数进行的静态函数调用,这并不美观,也不允许将数据直接传递回子类构造函数。所以我希望我们能做这样的事情:

public class ParentClass {

    public ParentClass(String x, Int32 y) {
        // ...
    }
}

public class Subclass : ParentClass {

    private static ComplexObject GetComplexObject() {
        // ...
    }

    public Subclass() {
        // All code before `base()` is executed in a static context:
        ComplexObject cmplx = GetComplexObject();
        base( cmplx.X, cmplx.Y );
    }
}
相反,我们目前需要这样做:

public Subclass()
    : base( GetComplexObject().X, GetComplexObject().Y ) {
}
或者使用带有私有构造函数的静态工厂方法:

private Subclass(String x, Int32 y) : base( x, y ) {

}

public static Subclass Create() {

    ComplexObject cmplx = GetComplexObject();
    return new Subclass( cmplx.X, cmplx.Y );
}
是的,这是正确的答案。我尝试过java,但几乎所有c代码的语法都不同。一旦你在你的子类上用构造函数调用基类,你就需要按照你从基类编码它的方式

您也可以在实例化时尝试此方法

 Baseclass base = new Baseclass(32);
是的,这是正确的答案。我尝试过java,但几乎所有c代码的语法都不同。一旦你在你的子类上用构造函数调用基类,你就需要按照你从基类编码它的方式

您也可以在实例化时尝试此方法

 Baseclass base = new Baseclass(32);