java - Java和C#的构造函数执行顺序及其对代码移植的实际影响

标签 java c# constructor

在这个问题中C# constructor execution order ,主要答案提到了

Note that in Java, the base class is initialized before variable initializers are run. If you ever port any code, this is an important difference to know about

我想知道是否存在因为这个问题而无法在 C# 构造函数和 Java 构造函数之间简单移植的真实示例?

如果是这样,这些示例只是故意设计的反模式还是它们存在于像某些开源项目这样的实际项目中?

更新:我们能否列出一个无法简单移植的模式列表,例如证明如果代码中没有这样的模式,可以简单地使用工具映射构造函数。

我的尝试(在@John的帮助下):根据该答案的评论,下面的代码不能简单地移植,但它是故意设计的:

C#:

class foo
{
    public foo()
    {
        if (this is bar)
        {
            (this as bar).test();
        }
    }
}

class bar : foo
{
    string str="str" ;
    public bar()
    {

    }

    public void test()
    {
        string s=str.Substring(1);
    }
}

Java:

static public class foo
{
    public foo()
    {
        if (this instanceof bar)
        {
            ((bar)this).test();
        }
    }
}

static public class bar extends foo
{
    String str="str" ;
    public bar()
    {

    }

    public void test()
    {
        String s=str.substring(1);
    }
}

最佳答案

在您链接到的答案中,Jon Skeet 提供了一个指向“a page with more details ”的链接,他在其中使用了以下示例:

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;
    }
}

When a new instance of MyDerivedClass is created in C#, the output is:

hello
hello

The first line is hello because the instance variable initializer for the name variable has run directly before the base class constructor. The equivalent code in Java syntax would output:

null
hello 

我不认为这个例子是特别做作的:有人会在基类中调用虚拟方法(如ToString()),这并非不可想象,虚拟方法也不会尝试使用成员变量。事实上,考虑到乔恩用两种语言编写了库及其端口,假设这是乔恩个人可能遇到的事情并不是很牵强。

但是,正如他提到的:

This is a really bad idea - wherever possible, only call non-virtual methods from constructors, and if you absolutely must call a virtual method, document very carefully that it is called from the constructor, so that people wishing to override it are aware that their object may not be in a consistent state when it is called (as their own constructor won't have run yet).

所以反模式:是的。故意设计的吗?也许不是。

关于java - Java和C#的构造函数执行顺序及其对代码移植的实际影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57764358/

相关文章:

java - 不可写属性异常 : Bean property 'dataSource' is not writable or has an invalid setter method

java - 以编程方式编辑/修改 .java 文件? (不是 .class 文件)

java - 监听多个输入流?

java - 附件不随 Spring 邮件发送

c++ - C++中初始化程序和默认初始化程序列表之间的区别

c# - 带有 Firebird 的 NHibernate ...是否启用了这些功能?

c# - 团结 : player moves up without any such code

c# - 查找嵌套和排序

c++ 对象初始化和构造函数语义

c# - 构造函数执行前的属性初始化