This is a C# question specifically inside the Unity environment (which may or may not be relevant here).
I have a specific condition in a Property as follows:
public override bool IsFinished
{
get
{
return buildable == null || (buildable != null && buildable.BuildingComplete);
}
}
The buildable variable is an IBuildable, which in this case is a GameObject that has already been destroyed through the GameObject.Destroy method.
Now this condition should in this situation be true because the gameObject has been destroyed, and the buildable variable is already null. However in Unity when you destroy a gameObject, you can still access that object's properties, even though the buildable == null
comparison returns true.
The problem is: even though buildable is actually null, the property returns false. Proof below:
Any ideas?
CodePudding user response:
The default value for boolean is false. In debugging mode, when a line is highlighted, execution is not run over it yet. So, that line is not executed and that expression is not computed yet. Just change that return statement to:
var result = buildable == null || (buildable != null && buildable.BuildingComplete);
return result;
Then put a breakpoint to result line and inspect result when that breakpoint is hit.
Btw, as @gunr2171 pointed out in a comment, buildable != null
is not needed in that expression.
CodePudding user response:
Thanks guys for the quick answer. The == operator is overriden indeed in Unity for this particular one (and there's not much I can do about it because it's in the library itself).
I rewrote it so you can see, I understand that the default value of a boolean is false.
As you can see here, even though the buildable is null, it can still be evaluated and there are actually values inside it. The only thing I can't wrap my head around is that the left condition is STILL true (buildable == null evaluates as true) but the result is false.
CodePudding user response:
Okay I just found out some legend has already found it out. It's because of Unity's operator overload, so here's the solution, I just tested and it works. Instead of using buildable == null, I'm using this method now and it works perfectly.
/// <summary>
/// Returns true if the object is either a null reference or has been destroyed by unity.
/// This will respect ISPDisposable over all else.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static bool IsNullOrDestroyed(this System.Object obj)
{
if (object.ReferenceEquals(obj, null)) return true;
if (obj is UnityEngine.Object) return (obj as UnityEngine.Object) == null;
return false;
}