c# - 为什么在非 MonoBehaviour 序列化类中调用多个构造函数?

标签 c# unity3d constructor execution inspector

我已将脚本附加到 Unity 游戏对象。该脚本包含各种公共(public)属性,包括我自己的一些类。就像在下面的简化代码中一样,其中 TestMonoBehaviorClass 附加到游戏对象,TestClass' TestString 显示在检查器中。

public class TestMonoBehaviorClass : MonoBehaviour
{
    public TestClass Test;
}

[System.Serializable]
public class TestClass
{
    public string TestString;
    public TestClass ()
    {
        Debug.Log ("TestClass creator called.");
        this.TestString = "Reset String";
    }
}

当我将脚本附加到游戏对象时,我希望 TestClass 的构造函数(编辑:不是从 MonoBehavior 派生的)被调用一次。但是如果我在 Unity 编辑器中运行程序然后停止程序,它会被调用四次。如果我将脚本附加到两个游戏对象,则可以执行七次。至少我多次在控制台中看到 Debug.Log 的输出。

不过,如果我在编辑器中更改 TestString 属性的内容,我手动输入的内容不会被覆盖!

为什么经常调用构造函数? 它在 Unity 的执行顺序 ( Unity's execution order of event functions ) 中何时被调用? 我可以忽略调用,还是必须在我的构造函数中添加特殊处理?到目前为止,我没有看到任何实际问题或副作用。

编辑: 好像只有没有参数的构造函数被调用了。如果我只有带参数的构造函数,则不会调用任何构造函数。

最佳答案

[System.Serializable] 是多次调用构造函数的原因。忽略它,除非因此导致错误,然后询问有关该特定错误的问题以获得变通解决方案。如果您删除 [System.Serializable],Unity 将不会序列化 TestClass 类,构造函数将被调用一次,而不是多次。

Edit: It seems that only constructors without parameters are called. If I only have constructors with parameters, then none is called.

使用[System.Serializable],Unity序列化会在序列化和淡化过程中多次调用默认构造函数,因为反序列化时需要重新创建Object。构造函数用于执行此操作。参见 this在 Unity 中发布其他类似的多构造函数调用问题。

<支持> 编辑:

如果你想在序列化完成之前或之后做一些事情,你可以实现 ISerializationCallbackReceiver界面并使用OnBeforeSerialize()OnAfterDeserialize()函数分别执行此操作。

例如:

[System.Serializable]
public class TestClass : ISerializationCallbackReceiver
{
    public string TestString;
    public TestClass()
    {
        Thread thread = Thread.CurrentThread;
        Debug.Log("TestClass creator called: " + thread.ManagedThreadId);

        this.TestString = "Reset String";
    }

    public void OnAfterDeserialize()
    {
        Thread thread = Thread.CurrentThread;
        Debug.LogWarning("OnAfterDeserialize Thread ID: " + thread.ManagedThreadId);
    }

    public void OnBeforeSerialize()
    {
        Thread thread = Thread.CurrentThread;
        Debug.LogWarning("OnBeforeSerialize Thread ID: " + thread.ManagedThreadId);
    }
}

关于c# - 为什么在非 MonoBehaviour 序列化类中调用多个构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46424378/

相关文章:

c# - 显示完整 InnerException 的正确方法是什么?

java - 没有任何构造函数的 JVM 字节码类是否有效?

c# - Task.WaitAll 上的 System.AggregateException

c# - Unity - 在游戏对象实例化后重绘/重绘场景

java - 用于 C# .Net 框架的 AndroidJavaClass 和 AndroidJavaObject

xcode - Xcode 运行时崩溃

c++ - 使用继承时构造函数/析构函数调用的顺序

ruby - 在类构造函数中有参数是否可以接受?

c# - SQL 查询的取值不超过 2100

c# - .NET 在编译前会优化代码吗?