Default Values and Object Initialization

I’m trying to figure out why the following code does not work.

using UnityEngine;

public class Foo : MonoBehaviour
{
    public class Bar
    {
        public float floatValue = 5.0f;
        public bool boolValue = true;

        public Bar()
        {
            Debug.Log( "Bar Constructor" );
            Debug.Log( "    floatValue: " + floatValue );
            Debug.Log( "    boolValue: " + boolValue );
        }
    }

    void Start()
    {
        var _bar = new Bar()
        {
            floatValue = 10.0f,
            boolValue = false
        };

        Debug.Log( "Checking Values" );
        Debug.Log( "    floatValue: " + _bar.floatValue );
        Debug.Log( "    boolValue: " + _bar.boolValue );
    }
}

The float value changes to 10.0f from the default value of 5.0f but the bool value is always true which is the default value. If i don’t assign a default value to the bool, it will accept a value of true from initialization.

This might be the expected behavior but I just want to know what the rules are when it comes to assigning default values and object initialization.

Adding that didn’t help :slight_smile:

Yeah sorry I miss read the problem I blame my small phone screen. Are you saying the boolValue = false is not working?

yeah, its always True

Aha. You seem to have stumbled across a Unity/Mono bug.

Just found it in our bug tracking system.
For the moment it seems to work if you do public bool boolValue; and don’t assign a default value.

Is that a valid way of instantiating an instance and setting values? I’ve never seen that before. Is it perhaps a new feature incompatible with Unity’s version of .NET?

Any particular reason you can’t pass arguments to the constructor or do:

var _bar = new Bar();
_bar.floatValue = 10.0f;
_bar.boolValue = false;

?

They are called Initializers, its a standard .Net feature that means you don’t need to create lots of constructors just to set values :wink:
The above code works fine outside of Unity(in both Visual Studio and MonoDevelop) and the bug only seems to with bool values :eyes:
However passing values through the constructor will solve the problem.

1 Like

Wow… You really had me worried there for a minute.

Instance field initializers are supposed to execute before the constructor and the constructor is supposed to execute before the object initializer, so that is one weird bug.

Seems to be a bug in the version of Mono we use:
http://lists.ximian.com/pipermail/mono-bugs/2010-June/101206.html

With the new roadmap, I see that there’s plans for an upgrade to the “in-editor runtime” after IL2CPP is out - but this sounds like something that needs a bug fix before that.

Do you roll out bugfixes to the in-house Mono version? Object initializers are pretty nifty to have around, but if bools just straight up doesn’t work…

I’m going to take a look at it tomorrow. First sleep…

1 Like

Its nice to know I’m not going crazy. It would be awesome to get this fixed cause I’m using object initializes everywhere. Thanks for looking into it.

I also got this issue. To be more precise about the bug: you cannot object-initialize a variable to its default value, but other values are ok. Whatever it is bool, int or float (didn’t test other types)

public int a = 3; // Cannot be object-initialized to 0, any other value is ok
public int b = 0; // Can be object-initilized to any value (the bug probably occurs if set to 0 with no visible effect)
public bool c = true; // Cannot be object-initialized to false
public bool d = false; // Can be object-initilized to true

Hi This is now fixed, just pushing it through. Should be out in a patch release in the near future.

I will post here when i have more details.

2 Likes

The same appears to be happening to me with numeric values. If an int/float has a default value in the class, and specifically a 0 is given in the initializer, it uses the default value.

Example

using UnityEngine;

public class Foo : MonoBehaviour
{
   public class Bar
   {
     public int intValue = 10;
     public float floatValue = 5f;

     public Bar() { }
   }

   void Start()
   {
     Bar testBar = new Bar
     {
       intValue = 0,
       floatValue = 0
     };

     Debug.Log("intValue: " + testBar.intValue);
     Debug.Log("floatValue: " + testBar.floatValue);
   }
}

Prints 10 and 5.

In addition, boolean values still do not seem to work correctly.

This is fixed in 5.2(including numeric values) which should be out in the near future or you can grab the beta if you have a pro licence. Ill chase up the backport for 5.1.