C#でオブジェクトの一般的なリストを作成し、そのリストをクローンしたいと考えています。リスト内のアイテムはクローン可能ですが、list.Clone()を実行するオプションはないようです。
list.Clone()
これを回避する簡単な方法はありますか?
要素が値型であれば、そのままでOKです。
List newList = new List(oldList);
しかし、それらの要素が参照型であり、ディープコピーが必要な場合(要素が適切に ICloneable を実装していると仮定した場合)、次のようにすることができます。
ICloneable
List oldList = new List(); List newList = new List(oldList.Count); oldList.ForEach((item) => { newList.Add((ICloneable)item.Clone()); });
もちろん、上記のジェネリックで ICloneable を置き換えて、ICloneable を実装している要素の型であれば何でもキャストします。
もしあなたの要素タイプが ICloneable をサポートしていなくても、コピーコンストラクタを持っている場合は、代わりにこのようにすることができます。
List oldList = new List(); List newList = new List(oldList.Count); oldList.ForEach((item)=> { newList.Add(new YourType(item)); });
個人的には、すべてのメンバーのディープコピーを保証する必要があるため、ICloneableは避けたいと思っています。その代わりに,コピーコンストラクタか,YourType.CopyFrom(YourType itemToCopy) のようなファクトリメソッドで,YourType の新しいインスタンスを返すことをお勧めします.
YourType.CopyFrom(YourType itemToCopy)
YourType
これらのオプションのいずれも,(拡張機能やその他の)メソッドでラップすることができます。
浅いコピーの場合は、代わりにジェネリックなListクラスのGetRangeメソッドを使うことができます。
List oldList = new List( ); // Populate oldList... List newList = oldList.GetRange(0, oldList.Count);
引用元:ジェネリック・レシピより
値の型だけを気にするなら...。
型を知っていて
前に型を知らない場合は、ヘルパー関数が必要になります。
List Clone(IEnumerable oldList) { return newList = new List(oldList); }
だけです。
List myNewList = Clone(myOldList);
要素が値型であれば、そのままでOKです。
しかし、それらの要素が参照型であり、ディープコピーが必要な場合(要素が適切に
ICloneable
を実装していると仮定した場合)、次のようにすることができます。もちろん、上記のジェネリックで
ICloneable
を置き換えて、ICloneable
を実装している要素の型であれば何でもキャストします。もしあなたの要素タイプが
ICloneable
をサポートしていなくても、コピーコンストラクタを持っている場合は、代わりにこのようにすることができます。個人的には、すべてのメンバーのディープコピーを保証する必要があるため、
ICloneable
は避けたいと思っています。その代わりに,コピーコンストラクタか,YourType.CopyFrom(YourType itemToCopy)
のようなファクトリメソッドで,YourType
の新しいインスタンスを返すことをお勧めします.これらのオプションのいずれも,(拡張機能やその他の)メソッドでラップすることができます。
浅いコピーの場合は、代わりにジェネリックなListクラスのGetRangeメソッドを使うことができます。
引用元:ジェネリック・レシピより
値の型だけを気にするなら...。
型を知っていて
前に型を知らない場合は、ヘルパー関数が必要になります。
だけです。