C#에 일반 객체 목록이 있는데 이 목록을 복제하고 싶습니다. 목록 내의 항목은 복제할 수 있지만 list.Clone()
을 수행할 수 있는 옵션이 없는 것 같습니다.
이 문제를 쉽게 해결할 수 있는 방법이 있나요?
요소가 값 유형인 경우 그냥 하면 됩니다:
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
의 새 인스턴스를 반환하는 YourType.CopyFrom(YourType itemToCopy)
와 같은 팩토리 메서드를 제안합니다.
이러한 옵션은 메서드(확장자 또는 기타)로 래핑할 수 있습니다.
얕은 복사본의 경우 일반 List 클래스의 GetRange 메서드를 대신 사용할 수 있습니다.
List<int> oldList = new List<int>( );
// Populate oldList...
List<int> newList = oldList.GetRange(0, oldList.Count);
인용 출처: 제네릭 레시피
public static object DeepClone(object obj)
{
object objResult = null;
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, obj);
ms.Position = 0;
objResult = bf.Deserialize(ms);
}
return objResult;
}
이는 함께 할 수 있는 방법 중 하나는 C # 과 .NET 2.0. 네 객체에는 单捞磐啊 스크램블된 ' [시리얼화가 가능합니다 ()]'. 새로 지어 수준들과 손실됩니다 참조이고 모든 게 목표다.
약간 수정 후 클론할 수도 있습니다.
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;
}
그냥 클론할 바뀌엇어요 호츨 네스토리스트 ()
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 }
>
실제 클론할 하는 경우를 제외하고 모든 단일 개체 내에 ',' 가장 좋은 방법은, T> List< 클론하려면 목록은 새로운 목록을 만들 수 없는 낡은 list 를 취합은 매개변수입니다.
List<T> myList = ...;
List<T> cloneOfMyList = new List<T>(myList);
'또는' 등 '미리스트 변경되는지 삽입하십시오 영향을 미치지 않을 것이라고 제거하시겠습니까 클로니오프마이리스트', 그 반대의 경우도 마찬가지입니다.
그러나 실제 객체에는 컨테인먼트하는 열거합니다 같은 두 가지 못하고 있다.
그리고 당신의 개체는 프로젝트의 경우 이미 참조되었습니다 뉴턴소프t.j슨 세리얼리세이블 항상 flfile. 수 있습니다.
List<T> newList = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(listToCopy))
아마도 가장 효과적인 방법은 하지 않으면 그것을하지 하지만 그렇게 하지 않고, 수많은 사람들이 you& # 39 개에 배 속도 차이 디이브이 수 있습니다.
public List<TEntity> Clone<TEntity>(List<TEntity> o1List) where TEntity : class , new()
{
List<TEntity> retList = new List<TEntity>();
try
{
Type sourceType = typeof(TEntity);
foreach(var o1 in o1List)
{
TEntity o2 = new TEntity();
foreach (PropertyInfo propInfo in (sourceType.GetProperties()))
{
var val = propInfo.GetValue(o1, null);
propInfo.SetValue(o2, val);
}
retList.Add(o2);
}
return retList;
}
catch
{
return retList;
}
}
public static Object CloneType(Object objtype)
{
Object lstfinal = new Object();
using (MemoryStream memStream = new MemoryStream())
{
BinaryFormatter binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
binaryFormatter.Serialize(memStream, objtype); memStream.Seek(0, SeekOrigin.Begin);
lstfinal = binaryFormatter.Deserialize(memStream);
}
return lstfinal;
}
이 경우, lucky # 39 i& 판매업체에서 판독합니다 누가 될 겁니다. 그러나 위해 내 클론할 방법, 내가 만든 인터페이스입니다 object 유형의 바뀌엇어요 반환하지 않습니다.
public interface IMyCloneable<T>
{
T Clone();
}
그럼 내가 지정된 확장명은:
public static List<T> Clone<T>(this List<T> listToClone) where T : IMyCloneable<T>
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
내 A / V 표시를 인터페이스입니다 avamar 백업이었습니다 구현 소프트웨어이다. 내가 하고 싶은 내 Clone () 메서드를 가지고 목록을 반품하십시오 비드마르크 (치로네이블 인터페이스입니다 그들이성년에 바뀌엇어요 동안 내 방식을 반환되기를 객체):
public class VidMark : IMyCloneable<VidMark>
{
public long Beg { get; set; }
public long End { get; set; }
public string Desc { get; set; }
public int Rank { get; set; } = 0;
public VidMark Clone()
{
return (VidMark)this.MemberwiseClone();
}
}
마지막으로, 사용 확장명은 클래스 내에:
private List<VidMark> _VidMarks;
private List<VidMark> _UndoVidMarks;
//Other methods instantiate and fill the lists
private void SetUndoVidMarks()
{
_UndoVidMarks = _VidMarks.Clone();
}
아무나 맘에 들어? 별다른 진전을?
확장 방법을 사용할 수 있습니다.
namespace extension
{
public class ext
{
public static List<double> clone(this List<double> t)
{
List<double> kop = new List<double>();
int x;
for (x = 0; x < t.Count; x++)
{
kop.Add(t[x]);
}
return kop;
}
};
}
예를 들어, 자신의 가치를 유형을 사용하여 모든 오브젝트도 클론할 수 있습니다 멤버여야 이 클래스:
public class matrix
{
public List<List<double>> mat;
public int rows,cols;
public matrix clone()
{
// create new object
matrix copy = new matrix();
// firstly I can directly copy rows and cols because they are value types
copy.rows = this.rows;
copy.cols = this.cols;
// but now I can no t directly copy mat because it is not value type so
int x;
// I assume I have clone method for List<double>
for(x=0;x<this.mat.count;x++)
{
copy.mat.Add(this.mat[x].clone());
}
// then mat is cloned
return copy; // and copy of original is returned
}
};
참고: 어떤 변화가 복사 (또는 클론) 의 경우 원래 오브젝트도 영향을 받지는 않습니다.
필요할 경우 이 용량이 동일한 클론된 목록을 볼 수 있습니다.
public static List<T> Clone<T>(this List<T> oldList)
{
var newList = new List<T>(oldList.Capacity);
newList.AddRange(oldList);
return newList;
}
내 친구 그레고어 티노 쉐퍼드도 한국증권선물거래소법을 쉽냐구요 솔루션을 사용하여 JavaScript 시리얼. 필요가 없다) 로 사용하는 것보다 훨씬 더 빨리 lionbridge 의 테스트 및 플래깅 클래스뿐만 제송즈리얼리처 비나리포매터 뉴턴소프트 사용하여 시리얼화가 가능합니다. 수 있는 방법을 함께 확장명은 객체당.
표준 .NET 자바스크리프체리아리처 옵션:
public static T DeepCopy<T>(this T value)
{
JavaScriptSerializer js = new JavaScriptSerializer();
string json = js.Serialize(value);
return js.Deserialize<T>(json);
}
빠른 옵션을 사용하여 뉴턴소프트 JSON:
public static T DeepCopy<T>(this T value)
{
string json = JsonConvert.SerializeObject(value);
return JsonConvert.DeserializeObject<T>(json);
}