En C #, ¿es posible lanzar una Lista a la Lista ?

Quiero hacer algo como esto:

List childList = new List(); ... List parentList = childList; 

Sin embargo, como parentList es una lista de antepasados ​​del niño, en lugar de un ancestro directo, no puedo hacerlo. ¿Hay una solución (aparte de agregar cada elemento individualmente)?

No se permite el lanzamiento directo porque no hay forma de hacerlo seguro. Si tienes una lista de jirafas y la incluyes en una lista de animales, ¡podrías poner un tigre en una lista de jirafas! El comstackdor no lo detendrá, porque, por supuesto, un tigre puede entrar en una lista de animales. El único lugar que el comstackdor puede detenerte es la conversión insegura.

En C # 4 respaldaremos la covarianza y la contravariancia de las interfaces SAFE y los tipos de delegates que se parametrizan con tipos de referencia. Mira aquí para más detalles:

http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx

Usando LINQ:

 List parentList = childList.Cast().ToList(); 

Documentación para Cast<>()

Allá por el año 2009, Eric se burló de nosotros de que las cosas cambiarían en C # 4. Entonces, ¿dónde nos encontramos hoy?

Las clases usadas en mi respuesta se pueden encontrar en la parte inferior. Para que esto sea más fácil de seguir, usaremos una clase de Mammal como “padre” y las clases de Cat y Dog como “niños”. Los gatos y los perros son mamíferos, pero un gato no es un perro y un perro no es un gato.

Esto todavía no es legal, y no puede ser:

 List cats = new List(); List mammals = cats; 

Por qué no? Los gatos son mamíferos, entonces ¿por qué no podemos asignar una lista de gatos a una List ?

Porque, si se nos permitiera almacenar una referencia a una List en una variable List , entonces podríamos comstackr el siguiente código para agregar un perro a una lista de gatos:

 mammals.Add(new Dog()); 

¡No debemos permitir eso! Recuerde, los mammals son solo una referencia a los cats . Dog no desciende de Cat y no tiene importancia comercial en una lista de objetos Cat .

Comenzando con .NET Framework 4 , varias interfaces genéricas tienen parámetros de tipo covariantes declarados con la palabra clave out Generic Modifier introducida en C # 4. Entre estas interfaces está IEnumerable que, por supuesto, está implementado por List .

Eso significa que ahora podemos convertir un List a un IEnumerable :

 IEnumerable mammalsEnumerable = cats; 

No podemos agregar un nuevo Dog a los mammalsEnumerable porque IEnumerable es una interfaz de “solo lectura”, es decir, no tiene el método Add() , pero ahora podemos usar cats donde se pueda consumir un IEnumerable . Por ejemplo, podemos concatenar mammalsEnumerable con una List para devolver una nueva secuencia:

 void Main() { List cats = new List { new Cat() }; IEnumerable mammalsEnumerable = AddDogs(cats); // AddDogs() takes an IEnumerable Console.WriteLine(mammalsEnumerable.Count()); // Output: 3. One cat, two dogs. } public IEnumerable AddDogs(IEnumerable parentSequence) { List dogs = new List { new Dog(), new Dog() }; return parentSequence.Concat(dogs); } 

Definiciones de clase:

 public abstract class Mammal { } public class Cat: Mammal { } public class Dog : Mammal { } 

sí, puedes hacerlo como

 var result = List.And(x => x.Parent.All(b => b.ParentId == value)); 

Puede hacerlo utilizando un enfoque Linq del método de extensión de aplicación, es decir:

 List parentList = childList.Cast().ToList();