Help with c# ?? operator problem.

Hi,

i have:

myAudioSource = audio == null ? gameObject.AddComponent<AudioSource>() : audio; // working
// alternative
myAudioSource = audio ?? gameObject.AddComponent<AudioSource>();  // <--- not working?

NOTE: “audio” is a field from a baseclass

The first version was the org. code i copy&pasted, now VS + ReShaper “correctly” tells me that i can convert this expression to a ?? expression. The problem is that using the second expression the audiosource is not created?

I’m missing something, since from my point of view the two should be equal expressions?

Thx Andy

?? indicates that if the expression on left side is null, it will take the expression on the right side. It should work…

Unity created some equality/inequality checks as some implicit casts which may disturb this a little bit. null may in Unitys case (everything inherited from UnityEngine.Object) not be a real null.

If you’re right, why the first line is working? It’s also a null test.

The first one will call the equality operator from UnityEngine.Object, the second does a real null check. In Unity == null means that the object is either really null or marked as destroyed.

This:

GameObject a = null;
GameObject b = a == null ? new GameObject() : a;

Becomes:

IL_0001:  ldnull
IL_0002:  stloc.0
IL_0003:  ldloc.0
IL_0004:  ldnull
IL_0005:  call       bool [UnityEngine]UnityEngine.Object::op_Equality(class [UnityEngine]UnityEngine.Object,
                                                                     class [UnityEngine]UnityEngine.Object)
IL_000a:  brtrue.s   IL_000f
IL_000c:  ldloc.0
IL_000d:  br.s       IL_0014
IL_000f:  newobj     instance void [UnityEngine]UnityEngine.GameObject::.ctor()
IL_0014:  stloc.1

and this:

GameObject a = null;
GameObject b = a ?? new GameObject();

Becomes:

IL_0001:  ldnull
IL_0002:  stloc.0
IL_0003:  ldloc.0
IL_0004:  dup
IL_0005:  brtrue.s   IL_000d
IL_0007:  pop
IL_0008:  newobj     instance void [UnityEngine]UnityEngine.GameObject::.ctor()
IL_000d:  stloc.1

Edit:
Why this fails for the op is unclear to me, maybe audio has a stub value but is internal marked as not existing/destroyed.

Thanks for the informations.
Maybe it’s not working because audio is a shortcut to the component.
If you try GetComponent() it could be different…

audio does this internally :wink:

Thx for the infos,

“audio” is actually a default property from UnityEngine.Component

public AudioSource audio { [WrapperlessIcall, MethodImpl(MethodImplOptions.InternalCall)] get; }

I still don’t get why “??” fails, in this case.

As I never seen the code behind it, I can’t tell that, but I can trust you for sure.

audio might do that internally but it might not be the same pattern as transform because a GameObject must have a Transform whereas it can optionally have an AudioSource.