c# - significa - nulo asignación de operador coalescente a uno mismo
que significa+= en programacion (2)
No es realmente una respuesta completa a su pregunta y un ejemplo muy interesante, pero realicé algunas pruebas, y parece que el problema está en el atributo SerializeField
.
Cuando ejecuto esto (se asigna nullObj
del inspector nullObj
se deja vacío):
public AudioClip someObj;
[SerializeField]
private AudioClip nullObj;
void Start ()
{
Debug.Log("nullObj == null : " + (nullObj == null));
Debug.Log("someObj == null : " + (someObj == null));
nullObj = nullObj ?? someObj;
Debug.Log ("nullObj == null : " + (nullObj == null));
}
Tengo estas impresiones:
Sin embargo, deshacerse del atributo SerializeField
hace que todo funcione como se esperaba:
public AudioClip someObj;
private AudioClip nullObj;
void Start ()
{
Debug.Log("nullObj == null : " + (nullObj == null));
Debug.Log("someObj == null : " + (someObj == null));
nullObj = nullObj ?? someObj;
Debug.Log ("nullObj == null : " + (nullObj == null));
}
da:
Así que reflexionando:
Realmente no conozco la raíz del problema, pero lo que sí es cierto es que los campos de serialización de Unity3D interrumpen el funcionamiento de un operador coalescente nulo en el motor Mono. Todavía no sé cómo, pero tal vez solo debido al cambio ==
operador de tipo seriazlized ??
De todos modos, espero que ayude al menos un poco.
Actualmente tengo dos scripts configurados en Unity para manejar algunos UI Audio. Uno es gerente y el otro está allí para reproducir un sonido para un elemento de IU específico. Una versión simplificada de lo que tengo es esto:
public class AudioUIManager : MonoBehaviour //Only one of these in the scene
{
public AudioClip genericUISound; //This is set in the inspector.
}
public class AudioUITextAnimation : MonoBehaviour
{
[SerializeField]
private AudioClip specifiedUISound; //This is not set in the inspector
[SerializeField]
private AudioUIManager audioUIManager; // I get a reference to this elsewhere
void Start()
{
//Use generic sounds from audio manager if nothing is specified.
specifiedUISound = specifiedUISound ?? audioUIManager.genericUISound;
print(specifiedUISound);
}
}
Lo que intento lograr aquí es hacer que el campo specifiedUISound
use el sonido que se le asigna en el inspector. Si no se asigna ningún sonido, utilice el sonido genérico del administrador de la interfaz de usuario. Esto me ahorra asignar el mismo sonido a millones de botones que requieren el mismo sonido, pero me da la opción de tener un sonido específico para un botón si quiero.
Sin embargo , el operador de coalescencia null
está asignando null
a UISound specifiedUISound
a pesar de que es nulo y el sonido de audioUIManager
no lo está . Además, puedo hacer que esto funcione si utilizo el operador ternario para verificar nulo así:
specifiedUISound = specifiedUIsound == null ? audioUIManager.genericUISound : specifiedUISound;
¿Estoy malinterpretando el operador nulo coalescente? ¿Por qué pasó esto?
Editar: Jerry Switalski ha señalado que esto solo ocurre cuando el specifiedUISound
se serializa. (si es public
o si tiene el atributo [SerializeField]
). ¿Alguien puede arrojar algo de luz sobre lo que está pasando aquí?
Te estás cruzando con el operador de igualdad personalizado de Unity:
Cuando un MonoBehaviour tiene campos, solo en el editor, no establecemos esos campos en "nulo real", sino en un objeto "falso nulo". Nuestro operador == personalizado puede verificar si algo es uno de estos objetos nulos falsos y se comporta de manera acorde. Si bien esta es una configuración exótica, nos permite almacenar información en el objeto nulo falso que le brinda más información contextual cuando se invoca un método o cuando se solicita una propiedad al objeto. Sin este truco, solo obtendría una NullReferenceException, un seguimiento de pila, pero no tendría idea de qué GameObject tenía el MonoBehaviour que tenía el campo que era nulo.
Mientras se ejecuta en el editor, Unity reemplaza su null
serializado con un valor centinela que en realidad no es null
. Esto les permite proporcionar mensajes de error más informativos en algunas circunstancias.
¿Se specifiedUISound
igual a null
? Eso depende de cómo preguntes. C # tiene nociones múltiples de "igualdad", incluida la igualdad de datos y la igualdad de referencia .
Algunos controles dirán que los valores son iguales: ==
y Object.Equals
Otros dirán que no son iguales: ??
y Object.ReferenceEquals
Este comportamiento solo ocurrirá en el editor. Cuando se ejecuta en una versión independiente, cualquier valor null
será null
.