I am trying to use the null-coalescing operator in a C# script in Unity, my project Scripting Runtime is set to .NET 4.x so it should work correctly.
The problem is that even though the LEFT operand evaluates to null, it does not correctly return the RIGHT operand.
Here is an example statement that does NOT work when the left Operand returns null:
m_meshFilter = ( GetMeshFilter() ?? AddMeshFilter() );
Here is the SAME exact statement, except it explicitly passes null to the null-coalescing operator (this works correctly when run)
m_meshFilter = ( GetMeshFilter() == null ? null : GetMeshFilter() ) ?? AddMeshFilter();
Here is a short script to easily test the problem directly in Unity.
using UnityEngine;
public class DoubleQuestionTest : MonoBehaviour
{
public GameObject myGo;
public MeshFilter m_meshFilter = null;
[ContextMenu( "Test1 Null Coalescing Operator" )]
void Test1()
{
m_meshFilter = ( GetMeshFilter() ?? AddMeshFilter() );
if ( m_meshFilter == null )
{
Debug.Log( "m_meshFilter was null, trying Alternate" );
m_meshFilter = ( GetMeshFilter() == null ? null : GetMeshFilter() ) ?? AddMeshFilter();
}
}
MeshFilter GetMeshFilter()
{
MeshFilter temp = myGo.GetComponent<MeshFilter>();
if ( temp == null )
Debug.Log( " > Get Mesh Filter RETURNING NULL" );
return temp;
}
MeshFilter AddMeshFilter()
{
Debug.Log( " > Add Mesh Filter Called" );
return myGo.AddComponent<MeshFilter>();
}
}
You can run the test function by clicking the top right corner of the Component in the Inspector in Unity (2018.3.12f1)
When using the test script, the first use of the Null Coalescing operator will fail, but the second succeeds when I check for null explicitly, and then redundantly pass null (with the ternary operator)
Output in Unity Editor Console:
!
Is this a bug? or am I doing something wrong?
_______________________________
EDIT:
In looking for a workaround I found a decent way to make return REAL null for the sake of the null-coalescing operator:
public static T GetComponentRealNull<T>( this GameObject self ) where T : Component
{
T component = self.GetComponent<T>();
if ( component == null )
return null;
return component;
}
Or for more specific cases of adding/getting components:
public static T GetComponentOrAddIfMissing<T>(this GameObject self) where T : Component
{
T component = self.GetComponent<T>();
if(component == null)
component = self.AddComponent<T>();
return component;
}