我在c#中有一个对象的通用列表,并希望克隆列表。列表中的项是可克隆的,但似乎没有做list. clone()的选项。

有什么简单的办法吗?


当前回答

在这种情况下,对于浅拷贝,使用强制转换可能会有所帮助:

IList CloneList(IList list)
{
    IList result;
    result = (IList)Activator.CreateInstance(list.GetType());
    foreach (object item in list) result.Add(item);
    return result;
}

适用于通用列表:

List<T> Clone<T>(List<T> argument) => (List<T>)CloneList(argument);

其他回答

您还可以使用ToArray简单地将列表转换为数组,然后使用array . clone(…)克隆数组。 根据您的需要,Array类中包含的方法可以满足您的需要。

对于深度克隆,我使用反射如下:

public List<T> CloneList<T>(IEnumerable<T> listToClone) {
    Type listType = listToClone.GetType();
    Type elementType = listType.GetGenericArguments()[0];
    List<T> listCopy = new List<T>();
    foreach (T item in listToClone) {
        object itemCopy = Activator.CreateInstance(elementType);
        foreach (PropertyInfo property in elementType.GetProperties()) {
            elementType.GetProperty(property.Name).SetValue(itemCopy, property.GetValue(item));
        }
        listCopy.Add((T)itemCopy);
    }
    return listCopy;
}

你可以交替使用List或IEnumerable。

稍加修改后,你也可以克隆:

public static T DeepClone<T>(T obj)
{
    T objResult;
    using (MemoryStream ms = new MemoryStream())
    {
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms, obj);
        ms.Position = 0;
        objResult = (T)bf.Deserialize(ms);
    }
    return objResult;
}

您可以使用扩展方法。

static class Extensions
{
    public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
    {
        return listToClone.Select(item => (T)item.Clone()).ToList();
    }
}

对于浅拷贝,您可以使用泛型List类的GetRange方法。

List<int> oldList = new List<int>( );
// Populate oldList...

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

引用自:generic Recipes