C#で(またはの代わりに) CopyTo()
toのようなものを実装する「簡単な」方法はありますか?新しいオブジェクトを作成したくないのは、古いオブジェクトを保持しているすべての人が新しいオブジェクトの属性を確認できるようにするためです。これは完全に異なる場合があります。これらのほとんどは、抽象関数を保持できる親クラスから派生していますが、すべてのメンバーを1つずつコピーするためだけに数百行のコードを記述したくはありません。これを全体にコピーする必要があるかもしれません(悪いデザインですが、私のものではなく、書き直されていません)。マイクロソフトがこのためのインターフェースを作成したように見えますか、それとも私は何かを大いに見逃していましたか?MemberwiseCopy
Clone()
MemberwiseClone
4 に答える
質問はありません。既存のオブジェクトへの参照を作成したいようです。
C#のオブジェクトへの変数は、オブジェクトへの参照を保持しているだけなので、既存のオブジェクトに変数を割り当てても、同じオブジェクトにアクセスし続けます。
Object x = new Object();
Object y = x;
x.MyProperty = "hello";
上記のコードの場合、y.MyProperty=="hello"も同様です。
ディープコピーを取得しようとしていますか?つまり、参照型を持つすべてのフィールドが、最初に参照されたオブジェクトのMemberwiseClone()に無限に設定されているものですか?
シリアル化/逆シリアル化は、これを行うための「最も簡単な」方法だと思います。さらに、固定されたハンドルを使用して、より高速に実行する方法があります。
あなたはそのようにマーシャルとGCHandleを使うことができます(このリンクから):
public static object RawDeserializeEx( byte[] rawdatas, Type anytype )
{
int rawsize = Marshal.SizeOf( anytype );
if( rawsize > rawdatas.Length )
return null;
GCHandle handle = GCHandle.Alloc( rawdatas, GCHandleType.Pinned );
IntPtr buffer = handle.AddrOfPinnedObject();
object retobj = Marshal.PtrToStructure( buffer, anytype );
handle.Free();
return retobj;
}
public static byte[] RawSerializeEx( object anything )
{
int rawsize = Marshal.SizeOf( anything );
byte[] rawdatas = new byte[ rawsize ];
GCHandle handle = GCHandle.Alloc( rawdatas, GCHandleType.Pinned );
IntPtr buffer = handle.AddrOfPinnedObject();
Marshal.StructureToPtr( anything, buffer, false );
handle.Free();
return rawdatas;
}
メモリストリームへのシリアル化とインスタンスへの逆シリアル化を使用できます。
私たちのプロジェクトには、そのような「DeepCopy」メソッドがあります。ちょっと危険です。信頼性が高く、最終的に制御が強化されるため、copy-property-methodsまたはcopyコンストラクターをクラスに実装し始めました。
オブジェクトの既存のすべてのフィールドを別のインスタンスの値で上書きする場合、簡単な方法はありません。オブジェクトの各フィールドにアクセスして値をコピーするために、風変わりなリフレクションコードを記述したい場合は、これを行うことができます。しかし、それは壊れやすく、厄介です。
さらに、それを正しく行うには、オブジェクトの継承ツリーをたどり、同じ割り当て操作を実行する必要があります。
最後に、オブジェクトにreadonly
フィールドが含まれている場合、別のインスタンスの正確な状態をコピーできない可能性があり、一貫性のないコピーがコピーの許容可能な結果であるかどうかを判断する必要があります。