在C#中,字段初始化器和对象初始化器是如何交互的
本文关键字:初始化 何交互 交互 对象 字段 | 更新日期: 2023-09-27 17:53:45
我主要是一名C++开发人员,但最近我一直在用C#进行一个项目。今天,在使用对象初始值设定项时,我遇到了一些意想不到的行为,至少对我来说是这样。我希望这里有人能解释发生了什么。
示例A
public class Foo {
public bool Bar = false;
}
PassInFoo( new Foo { Bar = true } );
示例B
public class Foo {
public bool Bar = true;
}
PassInFoo( new Foo { Bar = false } );
例A如我所料。传递到PassInFoo的对象的Bar设置为true。然而,在示例B中,foo。Bar设置为true,尽管在对象初始值设定项中被赋值为false。是什么导致示例B中的对象初始值设定项看起来被忽略了?
我在Mono的Unity3d构建中确认了这个丑陋的错误(Mono 2.6.5,Unity3d 4.1.2f1,OSX(。
看起来它不喜欢使用ValueType的默认值,所以您可以很好地传递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);}
}
在非unity3d OSX Mono 2.10.11(Mono-2-10/2baeee2美国东部时间2013年1月16日星期三16:40:16(上,测试运行良好:
FOO1: True
FOO2: False
FOO1i: 42
FOO2i: 0
FOO2i: 13
编辑:在unity3d的错误跟踪器中填写了一个错误:https://fogbugz.unity3d.com/default.asp?548851_3gh8hi55oum1btda
查看正在发生的事情的最简单方法是将语句分解为等价语句(如果逐行执行(。
原件:
PassInFoo( new Foo { Bar = false } );
断开:
var tmp = new Foo(); //Bar initialized to true
tmp.Bar = false;
PassInFoo( tmp );
我在Unity&单声道。
我通过初始化构造函数中的字段,然后用对象初始化器重写来绕过它。
然而!起初这也不起作用。因此,我用带有支持字段的属性替换了字段,这似乎强制了预期的行为。
class Program
{
static void Main(string[] args)
{
PassInFoo( new Foo { Bar = false } );
}
public class Foo
{
public bool Bar = true;
}
public static void PassInFoo(Foo obj)
{
Console.WriteLine(obj.Bar.ToString());
Console.ReadLine();
}
}
当使用Framework 3.5进行验证时,上面的代码运行良好(控制台窗口上显示false(。