¿Cómo puedo clonar una lista genérica en C#?

Tengo una lista genérica de objetos en C#, y deseo clonar la lista. Los elementos dentro de la lista son clonables, pero no parece haber una opción para hacer list.Clone().

¿Hay alguna manera fácil de evitar esto?

Si tus elementos son de tipo valor, entonces puedes hacer simplemente:

List newList = new List(oldList);

Sin embargo, si son tipos de referencia y quieres una copia profunda (asumiendo que tus elementos implementan correctamente ICloneable), podrías hacer algo como esto:

List oldList = new List();
List newList = new List(oldList.Count);

oldList.ForEach((item) =>
    {
        newList.Add((ICloneable)item.Clone());
    });

Obviamente, sustituye ICloneable en los genéricos anteriores y castéalo con el tipo de elemento que implementa ICloneable.

Si tu tipo de elemento no soporta ICloneable pero tiene un constructor de copias, puedes hacer esto en su lugar:

List oldList = new List();
List newList = new List(oldList.Count);

oldList.ForEach((item)=>
    {
        newList.Add(new YourType(item));
    });

Personalmente, evitaría ICloneable por la necesidad de garantizar una copia profunda de todos los miembros. En su lugar, sugeriría el constructor-copia o un método de fábrica como SuTipo.CopiarDe(SuTipo elementoParaCopiar) que devuelva una nueva instancia de SuTipo.

Cualquiera de estas opciones podría ser envuelta por un método (extensión o no).

Comentarios (21)

Para obtener una copia superficial, puede utilizar el método GetRange de la clase genérica List.

List oldList = new List( );
// Populate oldList...

List newList = oldList.GetRange(0, oldList.Count);

Citado de: Recetas Genéricas

Comentarios (2)

Si sólo te importan los tipos de valores...

Y conoces el tipo:

List newList = new List(oldList);

Si no conoces el tipo antes, necesitarás una función de ayuda:

List Clone(IEnumerable oldList)
{
    return newList = new List(oldList);
}

El justo:

List myNewList = Clone(myOldList);
Comentarios (2)