[c#] C #에서 일반 목록을 어떻게 복제합니까?



Answers

요소가 값 유형이면 다음과 같이 할 수 있습니다.

List<YourType> newList = new List<YourType>(oldList);

그러나 참조 유형이고 전체 복사 ( ICloneable 제대로 구현한다고 가정 할 때)를 원하면 다음과 같이 할 수 있습니다.

List<ICloneable> oldList = new List<ICloneable>();
List<ICloneable> newList = new List<ICloneable>(oldList.Count);

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

분명히 위의 제네릭에서 ICloneable 을 대체하고 ICloneable 을 구현하는 요소 유형이 무엇이든지간에 캐스트하십시오.

요소 유형이 ICloneable 지원하지 않지만 복사 생성자가있는 경우 대신 다음을 수행 할 수 있습니다.

List<YourType> oldList = new List<YourType>();
List<YourType> newList = new List<YourType>(oldList.Count);

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

개인적으로, 나는 모든 회원의 완전한 사본을 보증 할 필요가 있기 때문에 ICloneable 을 피할 것입니다. 대신 복사 생성자 또는 YourType.CopyFrom(YourType itemToCopy) 의 새 인스턴스를 반환하는 YourType.CopyFrom(YourType itemToCopy) 과 같은 팩터 리 메서드를 제안합니다.

이러한 옵션은 메소드 (확장 또는 기타)로 랩핑 될 수 있습니다.

Question

C #에서 객체의 일반적인 목록을 가지고 있으며 목록을 복제하려고합니다. 목록 내의 항목은 복제 가능하지만 list.Clone() 을 수행하는 옵션이없는 것 같습니다.

이 문제를 해결하는 쉬운 방법이 있습니까?




목록을 복제하려면 .ToList ()를 호출하면됩니다.

Microsoft (R) Roslyn C# Compiler version 2.3.2.62116
Loading context from 'CSharpInteractive.rsp'.
Type "#help" for more information.
> var x = new List<int>() { 3, 4 };
> var y = x.ToList();
> x.Add(5)
> x
List<int>(3) { 3, 4, 5 }
> y
List<int>(2) { 3, 4 }
> 



얕은 복사본의 경우 일반 List 클래스의 GetRange 메서드를 대신 사용할 수 있습니다.

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

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

인용구 : 제네릭 요리법




ToArray 사용하여 목록을 배열로 변환 한 다음 Array.Clone(...) 사용하여 배열을 복제 할 수도 있습니다. 필요에 따라 Array 클래스에 포함 된 메서드가 사용자의 요구를 충족시킬 수 있습니다.




public class CloneableList<T> : List<T>, ICloneable where T : ICloneable
{
  public object Clone()
  {
    var clone = new List<T>();
    ForEach(item => clone.Add((T)item.Clone()));
    return clone;
  }
}



JSON 시리얼 라이저와 디시리얼라이저를 사용하여 C #에서 객체를 복제하는 간단한 방법이 있습니다.

확장 클래스를 만들 수 있습니다.

using Newtonsoft.Json;

static class typeExtensions
{
    [Extension()]
    public static T jsonCloneObject<T>(T source)
    {
    string json = JsonConvert.SerializeObject(source);
    return JsonConvert.DeserializeObject<T>(json);
    }
}

복제하고 대상을 지정하려면 다음을 수행하십시오.

obj clonedObj = originalObj.jsonCloneObject;



나는 IClonable을 구현하지 않는 항목의 ICollection을 변환하는 내 자신의 확장 프로그램을 만들었습니다.

static class CollectionExtensions
{
    public static ICollection<T> Clone<T>(this ICollection<T> listToClone)
    {
        var array = new T[listToClone.Count];
        listToClone.CopyTo(array,0);
        return array.ToList();
    }
}



다음 코드는 최소한의 변경으로 목록에 전송해야합니다.

기본적으로 각 연속 루프마다 더 큰 범위의 새로운 난수를 삽입하여 작동합니다. 이미 동일한 수 또는 그보다 많은 수의 숫자가있는 경우 해당 난수를 하나 위로 이동하여 더 큰 범위의 새로운 임의의 인덱스로 전송합니다.

// Example Usage
int[] indexes = getRandomUniqueIndexArray(selectFrom.Length, toSet.Length);

for(int i = 0; i < toSet.Length; i++)
    toSet[i] = selectFrom[indexes[i]];


private int[] getRandomUniqueIndexArray(int length, int count)
{
    if(count > length || count < 1 || length < 1)
        return new int[0];

    int[] toReturn = new int[count];
    if(count == length)
    {
        for(int i = 0; i < toReturn.Length; i++) toReturn[i] = i;
        return toReturn;
    }

    Random r = new Random();
    int startPos = count - 1;
    for(int i = startPos; i >= 0; i--)
    {
        int index = r.Next(length - i);
        for(int j = startPos; j > i; j--)
            if(toReturn[j] >= index)
                toReturn[j]++;
        toReturn[i] = index;
    }

    return toReturn;
}



동일한 용량의 복제 목록이 필요하면 다음을 시도해보십시오.

public static List<T> Clone<T>(this List<T> oldList)
{
    var newList = new List<T>(oldList.Capacity);
    newList.AddRange(oldList);
    return newList;
}



AutoMapper (또는 원하는 맵핑 라이브러리)를 사용하면 복제가 간단하고 유지 관리가 쉽습니다.

매핑 정의 :

Mapper.CreateMap<YourType, YourType>();

마술을해라 :

YourTypeList.ConvertAll(Mapper.Map<YourType, YourType>);



List<T> 안에있는 모든 단일 객체의 실제 복제본이 필요하지 않다면, 목록을 복제하는 가장 좋은 방법은 이전 목록을 가진 새로운 목록을 컬렉션 매개 변수로 만드는 것입니다.

List<T> myList = ...;
List<T> cloneOfMyList = new List<T>(myList);

삽입 또는 제거와 같은 myList 변경 사항은 cloneOfMyList 영향을주지 cloneOfMyList 그 반대의 경우도 마찬가지입니다.

그러나 두 목록에 포함 된 실제 개체는 여전히 동일합니다.




Related