una ultimo recorrer obtener objetos mostrar los lista guardar elemento datos como buscar c# .net generics covariance type-safety

ultimo - En C#, ¿por qué no se puede almacenar un objeto List<string> en una variable List<object>



obtener elemento de una lista c# (14)

Parece que un objeto de Lista no se puede almacenar en una variable de Lista en C #, y ni siquiera se puede convertir explícitamente de esa manera.

List<string> sl = new List<string>(); List<object> ol; ol = sl;

no se pueden convertir implícitamente el tipo System.Collections.Generic.List<string> a System.Collections.Generic.List<object>

Y entonces...

List<string> sl = new List<string>(); List<object> ol; ol = (List<object>)sl;

resultados en No se puede convertir el tipo System.Collections.Generic.List<string> a System.Collections.Generic.List<object>

Por supuesto, puede hacerlo sacando todo de la lista de cadenas y volviéndolo a poner uno a la vez, pero es una solución bastante complicada.


Aquí hay otra solución pre- .NET 3.5 para cualquier IList cuyo contenido pueda ser emitido implícitamente.

public IList<B> ConvertIList<D, B>(IList<D> list) where D : B { List<B> newList = new List<B>(); foreach (D item in list) { newList.Add(item); } return newList; }

(Basado en el ejemplo de Zooba)



Dicha covarianza en los genéricos no es compatible, pero en realidad puede hacer esto con matrices:

object[] a = new string[] {"spam", "eggs"};

C # realiza verificaciones de tiempo de ejecución para evitar que coloque, por ejemplo, un int en a .


Eso es en realidad para que no intentes poner ningún "objeto" impar en tu variante de la lista "ol" (como parece que la List<object> permitiría) - porque tu código se bloquearía entonces (porque la lista realmente es List<string> y solo aceptará objetos tipo String). Es por eso que no puedes convertir tu variable a una especificación más general.

En Java es al revés, no tiene genéricos, y en su lugar, todo es Lista de objetos en tiempo de ejecución, y realmente puede rellenar cualquier objeto extraño en su Lista de tipos supuestamente estrictos. Busque "Genéricos reificados" para ver una discusión más amplia del problema de Java ...


Esto tiene mucho que ver con la covarianza, por ejemplo, los tipos genéricos se consideran como parámetros, y si los parámetros no se resuelven correctamente a un tipo más específico, la operación falla. La implicación de esto es que realmente no se puede convertir a un tipo similar a un objeto más general. Y según lo establecido por Rex, el objeto List no convertirá cada objeto por usted.

Es posible que desee probar el código ff en su lugar:

List<string> sl = new List<string>(); //populate sl List<object> ol = new List<object>(sl);

o:

List<object> ol = new List<object>(); ol.AddRange(sl);

Ol (teóricamente) copiará todos los contenidos de sl sin problemas.


La razón es que una clase genérica como List<> es, para la mayoría de los propósitos, tratada externamente como una clase normal. por ejemplo, cuando dice List<string>() el compilador dice ListString() (que contiene cadenas). [Gente técnica: esta es una versión extremadamente simple de lo que está pasando en inglés]

En consecuencia, obviamente el compilador no puede ser lo suficientemente inteligente como para convertir un ListString en un ListObject al lanzar los elementos de su colección interna.

Es por eso que hay métodos de extensión para IEnumerable como Convert () que le permiten proporcionar fácilmente la conversión de los elementos almacenados dentro de una colección, lo que podría ser tan simple como la conversión de uno a otro.



Mm, gracias a los comentarios anteriores encontré dos maneras de averiguarlo. El primero es obtener la lista de elementos de la cadena y luego convertirla en la lista de objetos IEnumerable:

IEnumerable<object> ob; List<string> st = new List<string>(); ob = st.Cast<object>();

Y el segundo es evitar el tipo de objeto IEnumerable, simplemente convertir la cadena en tipo de objeto y luego usar la función "toList ()" en la misma oración:

List<string> st = new List<string>(); List<object> ob = st.Cast<object>().ToList();

Me gusta más la segunda forma. Espero que esto ayude.


No se puede convertir entre tipos genéricos con diferentes parámetros de tipo. Los tipos genéricos especializados no forman parte del mismo árbol de herencia y, por lo tanto, son tipos no relacionados.

Para hacer esto pre-NET 3.5:

List<string> sl = new List<string>(); // Add strings to sl List<object> ol = new List<object>(); foreach(string s in sl) { ol.Add((object)s); // The cast is performed implicitly even if omitted }

Usando Linq:

var sl = new List<string>(); // Add strings to sl var ol = new List<object>(sl.Cast<object>()); // OR var ol = sl.Cast<object>().ToList(); // OR (note that the cast to object here is required) var ol = sl.Select(s => (object)s).ToList();


Piénselo de esta manera, si tuviera que hacer una conversión de ese tipo y luego agregar un objeto de tipo Foo a la lista, la lista de cadenas ya no es consistente. Si tuviera que repetir la primera referencia, obtendría una excepción de conversión de clase porque una vez que llegara a la instancia de Foo, ¡no se podría convertir a Foo en una cadena!

Como nota al margen, creo que sería más significativo si puedes o no hacer el lanzamiento inverso:

List<object> ol = new List<object>(); List<string> sl; sl = (List<string>)ol;

No he usado C # por un tiempo, así que no sé si eso es legal, pero ese tipo de reparto es realmente (potencialmente) útil. En este caso, se pasa de una clase más general (objeto) a una clase más específica (cadena) que se extiende desde la general. De esta manera, si agrega a la lista de cadenas, no está violando la lista de objetos.

¿Alguien sabe o puede probar si dicho reparto es legal en C #?


Sí, puedes, desde .NET 3.5:

List<string> sl = new List<string>(); List<object> ol = sl.Cast<object>().ToList();


Si está utilizando .NET 3.5, eche un vistazo al método Enumerable.Cast. Es un método de extensión para que pueda llamarlo directamente en la Lista.

List<string> sl = new List<string>(); IEnumerable<object> ol; ol = sl.Cast<object>();

No es exactamente lo que pediste pero debería hacer el truco.

Edición: Como lo señaló Zooba, puede llamar a ol.ToList () para obtener una lista


Tengo un:

private List<Leerling> Leerlingen = new List<Leerling>();

Y lo iba a llenar con los datos recopilados en una List<object> Lo que finalmente me funcionó fue este:

Leerlingen = (List<Leerling>)_DeserialiseerLeerlingen._TeSerialiserenObjecten.Cast<Leerling>();

.Cast al tipo que desee para obtener un IEnumerable de ese tipo y, a continuación, IEnemuerable en la List<> que desee.


List<string> sl = new List<string>(); List<object> ol; ol = new List<object>(sl);