unity - validar si un objeto es null c#
La inicialización de la propiedad de la lista sin "nueva lista" provoca NullReferenceException (5)
La referencia a un valor nulo no se puede verificar siempre en el momento de la compilación Aunque el compilador a veces advierte sobre el uso de una variable antes de que haya sido asignada. El compilador funciona correctamente. Este es un error en tiempo de ejecución.
using System;
using System.Collections.Generic;
class Parent
{
public Child Child { get; set; }
}
class Child
{
public List<string> Strings { get; set; }
}
static class Program
{
static void Main() {
// bad object initialization
var parent = new Parent() {
Child = {
Strings = { "hello", "world" }
}
};
}
}
El programa anterior compila bien, pero falla en el tiempo de ejecución con la referencia del objeto no establecida en una instancia del objeto .
Si observa en el fragmento de código anterior, he omitido nuevo al inicializar las propiedades secundarias.
Obviamente la forma correcta de inicializar es:
var parent = new Parent() {
Child = new Child() {
Strings = new List<string> { "hello", "world" }
}
};
Mi pregunta es ¿por qué el compilador de C # no se queja cuando ve la primera construcción?
¿Por qué es válida la sintaxis de inicialización rota?
var parent = new Parent() {
Child = {
Strings = { "hello", "world" }
}
};
La segunda sintaxis es válida para propiedades de solo lectura. Si cambia el código para inicializar las propiedades de Niño y Cadenas en los constructores respectivos, la sintaxis funciona.
class Parent
{
public Parent()
{
Child = new Child();
}
public Child Child { get; private set; }
}
class Child
{
public Child()
{
Strings = new List<string>();
}
public List<string> Strings { get; private set; }
}
static class Program
{
static void Main()
{
// works fine now
var parent = new Parent
{
Child =
{
Strings = { "hello", "world" }
}
};
}
}
No es una sintaxis rota, eres tú quien usa un inicializador de objetos en una propiedad que simplemente no está instanciada. Lo que escribiste se puede ampliar a
var parent = new Parent();
parent.Child.Strings = new List<string> { "hello", "world" };
Que lanza la NullReferenceException
: está intentando asignar la propiedad Strings
contenidas por la propiedad Child
mientras que Child
sigue siendo null
. Usar un constructor para crear una instancia de Child
primero, se encarga de esto.
No hay nada malo con la inicialización, pero está intentando inicializar objetos que no existen.
Si las clases tienen constructores que crean los objetos, la inicialización funciona:
class Parent {
public Child Child { get; set; }
public Parent() {
Child = new Child();
}
}
class Child {
public List<string> Strings { get; set; }
public Child() {
Strings = new List<string>();
}
}
Parece que entiendes mal lo que hace el inicializador de colección.
Es un mero azúcar sintáctico que convierte la lista entre llaves en una serie de llamadas al método Add()
que debe definirse en el objeto de colección que se está inicializando.
Tu = { "hello", "world" }
por lo tanto tiene el mismo efecto que
.Add("hello");
.Add("world");
Obviamente, esto fallará con una NullReferenceException si no se crea la colección.