C#でオブジェクトの一般的なリストを作成し、そのリストをクローンしたいと考えています。リスト内のアイテムはクローン可能ですが、list.Clone()
を実行するオプションはないようです。
これを回避する簡単な方法はありますか?
要素が値型であれば、そのままでOKです。
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
の新しいインスタンスを返すことをお勧めします.
これらのオプションのいずれも,(拡張機能やその他の)メソッドでラップすることができます。
浅いコピーの場合は、代わりにジェネリックなListクラスのGetRangeメソッドを使うことができます。
List<int> oldList = new List<int>( );
// Populate oldList...
List<int> newList = oldList.GetRange(0, oldList.Count);
引用元:ジェネリック・レシピより
値の型だけを気にするなら...。
型を知っていて
List<int> newList = new List<int>(oldList);
前に型を知らない場合は、ヘルパー関数が必要になります。
List<T> Clone<T>(IEnumerable<T> oldList)
{
return newList = new List<T>(oldList);
}
だけです。
List<string> myNewList = Clone(myOldList);