Java和C#的构造函数执行顺序及其对代码移植的实际影响
在这个问题上,主要答覆提到: 请注意,在Java中,基类是在运行变量初始值设定项之前初始化的。如果您曾经移植过任何代码,这是一个需要了解的重要区别 我想知道,有没有真正的例子因为这个问题而不能简单地在C#构造函数和Java构造函数之间进行移植 如果是这样的话,这些示例是否只是故意设计的反模式,或者它们是否存在于像某些开源项目这样的实际项目中 更新:我们能否列出不能简单移植的模式,例如,证明如果代码中没有这样的模式,那么可以使用工具简单地映射构造函数 我的尝试(在@John的帮助下):根据对该答案的评论,下面的代码不能简单地移植,但它是经过精心设计的: C#: 爪哇:Java和C#的构造函数执行顺序及其对代码移植的实际影响,java,c#,constructor,Java,C#,Constructor,在这个问题上,主要答覆提到: 请注意,在Java中,基类是在运行变量初始值设定项之前初始化的。如果您曾经移植过任何代码,这是一个需要了解的重要区别 我想知道,有没有真正的例子因为这个问题而不能简单地在C#构造函数和Java构造函数之间进行移植 如果是这样的话,这些示例是否只是故意设计的反模式,或者它们是否存在于像某些开源项目这样的实际项目中 更新:我们能否列出不能简单移植的模式,例如,证明如果代码中没有这样的模式,那么可以使用工具简单地映射构造函数 我的尝试(在@John的帮助下):根据对该答案
在您链接到的答案中,Jon Skeet提供了一个指向“”的链接,他在其中使用了以下示例:
public class MyBaseClass
{
public MyBaseClass ()
{
Console.WriteLine (this.ToString());
}
}
public class MyDerivedClass : MyBaseClass
{
string name="hello";
public MyDerivedClass() : base()
{
Console.WriteLine (this.ToString());
}
public override string ToString()
{
return name;
}
}
在C#中创建MyDerivedClass的新实例时,输出为:
hello
hello
第一行是hello,因为name变量的实例变量初始值设定项直接在基类构造函数之前运行。Java语法中的等效代码将输出:
null
hello
我不认为这个例子是特别设计的:在基类中调用一个虚拟方法(如<>代码> toStRew()/代码>),也不是虚拟方法会尝试使用一个成员变量,这是不可想象的。事实上,考虑到Jon已经用两种语言编写了库及其端口,假设Jon个人可能会遇到这种情况并不牵强
但是,正如他提到的: 这是一个非常糟糕的想法-只要可能,只从构造函数调用非虚拟方法,如果您绝对必须调用虚拟方法,请非常仔细地记录它是从构造函数调用的,以便希望重写它的人知道,在调用它时,他们的对象可能不处于一致状态(因为他们自己的构造函数还没有运行) 所以反模式:是的。是故意设计的?也许不是。如果你想把它添加到你的问题中,我做了一个测试。但是是的,我观察到了相同的行为-str
为空。
hello
hello
null
hello