verificar valores valor validar tener referencia que objeto net instancia establecida error debe comprobar como asignar acepta c# linq anonymous-types

c# - valores - No se puede asignar null a la propiedad anónima de tipo array



verificar null c# (3)

Tengo cualquier conjunto de objetos ( Pilot ) con una propiedad ( Hanger ), que puede ser nula, que a su vez tiene una propiedad ( List<Plane> ). Para propósitos de prueba, quiero simplificar y ''aplanar'' esto a un objeto anónimo con las propiedades PilotName (cadena) y Planes (matriz) pero no estoy seguro de cómo manejar una propiedad de Hanger nula o una lista de PlanesList vacía.

(¿Por qué objetos anónimos? Porque los objetos de la API que estoy probando son de solo lectura y quiero que la prueba sea ''declarativa'': autocontenida, simple y legible ... pero estoy abierto a otras sugerencias. También estoy '' Estoy tratando de aprender más sobre LINQ.

ejemplo

class Pilot { public string Name; public Hanger Hanger; } class Hanger { public string Name; public List<Plane> PlaneList; } class Plane { public string Name; } [TestFixture] class General { [Test] public void Test() { var pilots = new Pilot[] { new Pilot() { Name = "Higgins" }, new Pilot() { Name = "Jones", Hanger = new Hanger() { Name = "Area 51", PlaneList = new List<Plane>() { new Plane { Name = "B-52" }, new Plane { Name = "F-14" } } } } }; var actual = pilots.Select(p => new { PilotName = p.Name, Planes = (p.Hanger == null || p.Hanger.PlaneList.Count == 0) ? null : p.Hanger.PlaneList.Select(h => ne { PlaneName = h.Name }).ToArray() }).ToArray(); var expected = new[] { new { PilotName = "Higgins", Planes = null }, new { PilotName = "Jones", Planes = new[] { new { PlaneName = "B-52" }, new { PlaneName = "F-14" } } } }; Assert.That(actual, Is.EqualTo(expected)); }

El problema inmediato es que la línea expected... Planes = null errores expected... Planes = null con,

No se puede asignar a una propiedad de tipo anónimo, pero admitir que el problema subyacente puede ser que usar null en actual es usar null no es el mejor enfoque en primer lugar.

¿Alguna idea de cómo asignar la matriz nula en expected o adoptar un enfoque diferente al null en actual ?


Hay dos cosas que suceden:

En primer lugar, cuando construye una instancia de un tipo anónimo utilizando el new { Name = Value} , para construir el tipo que necesita el compilador para poder calcular el tipo de Value . Solo el null por sí solo no tiene un tipo, por lo que el compilador no sabría qué tipo dar a su miembro Planes .

Ahora, si estuviera usando un tipo con nombre para el valor, simplemente podría decir (type)null y terminar, PERO porque desea una matriz de otro tipo anónimo, no hay manera de referirse a (¡es anónimo!).

Entonces, ¿cómo se escribe null como una matriz de un tipo anónimo? Bueno, la especificación de C # garantiza que los tipos anónimos con miembros con los mismos nombres y tipos (¡en el mismo orden!) Están unificados ; es decir, si decimos

var a = new { Foo = "Bar" }; var b = new { Foo = "Baz" };

entonces b tienen el mismo tipo . Podemos usar este hecho para obtener nuestro null adecuadamente tipeado así:

var array = (new[] { new { PlaneName = "" } }); array = null;

No es bonito pero funciona; ahora array tiene el tipo correcto pero un valor null . Así que esto compila:

var array = new[] { new { PlaneName = "" } }; array = null; var expected = new[] { new { PilotName = "Higgins", Planes = array }, new { PilotName = "Higgins", Planes = new[] { new { PlaneName = "B-52" }, new { PlaneName = "F-14" } } } };


Simplemente use el default(Plane[]) lugar de null .


Tienes que usar un nulo mecanografiado :

(List<Plane>)null

O

(Plane[])null

De lo contrario, el compilador no tiene idea de qué tipo quiere que sea el miembro del tipo anónimo.

Actualizar Como @AakashM ha señalado correctamente: esto resuelve su problema de asignar un null a un miembro anónimo, pero en realidad no se compila, y si lo hiciera, no le permitiría referirse a estos miembros.

Una solución sería hacer esto (desafortunadamente, tanto la matriz de Planes anónima como la null necesitarán ser lanzadas:

var expected = new[] { new { PilotName = "Higgins", Planes = (IEnumerable)null }, new { PilotName = "Higgins", Planes = (IEnumerable)new [] { new { PlaneName = "B-52" }, new { PlaneName = "F-14" } } } };

Así que usa IEnumerable como el tipo de miembro. También puede usar IEnumerable<object> pero el efecto será el mismo de cualquier manera.

O, podría usar IEnumerable<dynamic> como el tipo común, esto le permitiría hacer esto:

Assert.AreEqual("B-52", expected[1].Planes.First().PlaneName);