在C#中,字段初始化器和对象初始化器如何交互?

nsc*_*rag 5 c# mono initialization unity-game-engine

我主要是一名C++开发人员,但最近我一直在用C#开发一个项目.今天我在使用对象初始化器时遇到了一些意外的行为,至少对我来说是这样.我希望这里有人可以解释发生了什么.

例A

public class Foo {
    public bool Bar = false;
}

PassInFoo( new Foo { Bar = true } );
Run Code Online (Sandbox Code Playgroud)

例B

public class Foo {
    public bool Bar = true;
}

PassInFoo( new Foo { Bar = false } );
Run Code Online (Sandbox Code Playgroud)

示例A按照我的预期工作.传递给PassInFoo的对象将Bar设置为true.但是,在示例B中,尽管在对象初始值设定项中赋值为false,但foo.Bar设置为true.什么会导致示例B中的对象初始化程序看似被忽略?

Krz*_*rko 5

我在Unity的Unity3d版本(Mono 2.6.5,Unity3d 4.1.2f1,OSX)中确认了这个丑陋的错误.

它看起来像它不喜欢使用默认值的值类型,所以你可以传递int != 0,(bool)true等等就好了,但是在传递的默认值像(int)0或者(bool)false忽略它的价值.

证明:

using UnityEngine;
using System.Collections;

public class Foo1 {
    public bool Bar=false;
}

public class Foo2 {
    public bool Bar=true;
}

public class Foo1i {
    public int Bar=0;
}

public class Foo2i {
    public int Bar=42;
}

public class PropTest:MonoBehaviour {

    void Start() {
        PassInFoo(new Foo1 {Bar=true}); // FOO1: True (OK)
        PassInFoo(new Foo2 {Bar=false});/// FOO2: True (FAIL!)
        PassInFoo(new Foo1i {Bar=42});  // FOO1i: 42 (OK)
        PassInFoo(new Foo2i {Bar=0});/// FOO2i: 42 (FAIL!)
        PassInFoo(new Foo2i {Bar=13});/// FOO2i: 13 (OK)
    }

    void PassInFoo(Foo1 f) {Debug.Log("FOO1: "+f.Bar);}

    void PassInFoo(Foo2 f) {Debug.Log("FOO2: "+f.Bar);}

    void PassInFoo(Foo1i f) {Debug.Log("FOO1i: "+f.Bar);}

    void PassInFoo(Foo2i f) {Debug.Log("FOO2i: "+f.Bar);}
}
Run Code Online (Sandbox Code Playgroud)

在非unity3d OSX Mono 2.10.11(单声道2-10/2baeee2 Wed Jan 16 16:40:16 2013)上,测试运行良好:

FOO1: True
FOO2: False
FOO1i: 42
FOO2i: 0
FOO2i: 13
Run Code Online (Sandbox Code Playgroud)

编辑:填写了unity3d的bugtracker中的一个错误:https://fogbugz.unity3d.com/default.asp?548851_3gh8hi55oum1btda


Tho*_*mas 3

查看正在发生的情况的最简单方法是将您的语句分解为等效的语句(如果逐行完成)。

原来的:

PassInFoo( new Foo { Bar = false } );
Run Code Online (Sandbox Code Playgroud)

打破:

var tmp = new Foo();    //Bar initialized to true
tmp.Bar = false;
PassInFoo( tmp );
Run Code Online (Sandbox Code Playgroud)

  • @nschrag - 如果发现其中一个环境扰乱了评估顺序,那将是非常令人不安的。祝你好运! (2认同)