C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: ディープコピーの方法


(過去ログ 107 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■64005 / inTopicNo.1)  ディープコピーの方法
  
□投稿者/ howling (35回)-(2012/11/01(Thu) 19:29:13)

分類:[C#] 

こんばんわ。
C# / VS2010 / Windows7にて開発を行っております。

相変わらずプロパティグリッドにデータをずらっと表示して、それをセーブ…なんてことをしているのですが、
このデータをコピーする必要があるのをすっかり忘れたまま作業してました。

//これはディープコピー必須なので、後で書き換える
とかコメントで書いたまま3カ月以上が過ぎ…(バカ

データ自体は普段、XMLSerializerを使用してセーブ/ロードしているのですが、
データ自体がかなり大きいですし、内部に別のクラスオブジェクトをいくつも保持しているため、
どうしようかと頭を抱えてしまった状況です。

少し調べてみましたところ、
コピーコンストラクタを作成する方法(でも、全てのクラスに作らないとクラス内のクラスオブジェクトはシャローコピーになるのでひどく手間)
Object.MemberwiseCloneでシャローコピーをする方法(そもそもシャローコピー)
ICloneableを継承してCloneメソッド内に自分で定義する方法(でもこれってコピーコンストラクタと変わらないですよね)
シリアライズしてデシリアライズする方法がありました。

ここで、普段使用しているXMLSerializerを使って
シリアライズしてデシリアライズすれば良いのではないか?という結論に達しているのですが、
この場合どこかにXMLを一旦保存する必要があると思いますので、
それはそれでもっと良い方法がないかな?と思った次第です。



で、これとは別にunsafeコード内でデータ自体を取得するメソッドを自分で作っているのですが、
これはC++から呼び出しを行わせております。
こちらでできないかな?と試したのですが、C#から呼び出したらバッファオーバーランして逝ってしまわれました…。

//大雑把にはこんな感じ
void* pCopy = new byte[DataSize];
//確保しているDataSize分だけ現在のデータを取得
pComInterface->GetData(pCopy,DataSize);

//pCopyの中身を書き換え

//データセット
pComInterface->SetData(pCopy,DataSize);

さて、このGetDataメソッドをC#自身で呼ぼうとした場合に、
byte[] byteCopy = new byte[DataSize];

fixed(byte* pByte = &byteCopy[0])
{
GetData(pByte,DataSize); //オーバーランでさようなら
}

としてみたのですが、コメントの通りになってしまいました。
ちなみに、DataSizeはC++側とC#側と全く同じ数値です。
byteCopyで取得する配列というのが、メモリ上で並んでいるのか?というのが1つ疑問なのですが…
どうして逝かれてしまったし(お前のせいだ!)

というわけです。
いずれかの方法で良いのですが、うまくいかないものかと…。
もしくは別の楽な方法があれば教えて頂けませんでしょうか?

宜しくお願い致します。

引用返信 編集キー/
■64007 / inTopicNo.2)  Re[1]: ディープコピーの方法
□投稿者/ Jitta (12回)-(2012/11/01(Thu) 22:38:01)
Jitta さんの Web サイト
No64005 (howling さん) に返信
> ここで、普段使用しているXMLSerializerを使って
> シリアライズしてデシリアライズすれば良いのではないか?という結論に達しているのですが、
> この場合どこかにXMLを一旦保存する必要があると思いますので、
> それはそれでもっと良い方法がないかな?と思った次第です。

MemoryStream とか?
引用返信 編集キー/
■64011 / inTopicNo.3)  Re[2]: ディープコピーの方法
□投稿者/ Hongliang (15回)-(2012/11/02(Fri) 10:13:23)
ディープコピーのためのシリアライズにXmlSerializerを使うのは違和感。
BinaryFormatterのほうが自然かな。
いずれにしてもメンバの一部をシリアライズの対象外にできる手段も提供されているので、それで問題ないか確認する必要がありますが。

> コピーコンストラクタを作成する方法(でも、全てのクラスに作らないとクラス内のクラスオブジェクトはシャローコピーになるのでひどく手間)
> Object.MemberwiseCloneでシャローコピーをする方法(そもそもシャローコピー)
> ICloneableを継承してCloneメソッド内に自分で定義する方法(でもこれってコピーコンストラクタと変わらないですよね)

ICloneableは実装する必要はありませんが(このインターフェイスは非推奨です)、
コピーコンストラクタに比べてCloneメソッドを提供すればMemberwiseCloneを利用できるのでずいぶん楽でしょう。
一旦MemberwiseCloneした後で、より深くコピーする必要があるものだけ記述すればいいので。
引用返信 編集キー/
■64018 / inTopicNo.4)  Re[3]: ディープコピーの方法
□投稿者/ howling (38回)-(2012/11/02(Fri) 16:19:54)
Jittaさん、Hongliangさん

(少なくとも個人的には)有名なお二方にお返事頂けるとは感激です。
ありがとうございます。

MemoryStreamかBinaryFormatterでシリアライズする形を考えていきたいと思います。
個人的には前者で。ファイル自体を触らずにいけそうなので。

Cloneメソッドを提供してMemberwiseCloneという形はひどく綺麗だと思います。
あんまり深く考えずにそれをガガーッと書くのもアリだとは思うのですが、
現状やる気が出ないくらいには数があります(笑

とはいえ、ある程度コピペで済みますしね…。失念していた自分を呪います。

すみません、近日中にテストしますが、もう少々お時間をください。(とりあえず後回しにしてもらえたので)
またこちらで経過報告します。
ありがとうございました。

(その後で解決したらチェックするということで、一旦解決済みにはしないでおきます)
引用返信 編集キー/
■64025 / inTopicNo.5)  Re[4]: ディープコピーの方法
□投稿者/ Jitta (14回)-(2012/11/02(Fri) 21:59:37)
Jitta さんの Web サイト
No64018 (howling さん) に返信
> MemoryStreamかBinaryFormatterでシリアライズする形を考えていきたいと思います。
> 個人的には前者で。ファイル自体を触らずにいけそうなので。

"か"ではなく"と"ですよね?
フォーマッターとストリームは、両立させられます。
引用返信 編集キー/
■64089 / inTopicNo.6)  Re[5]: ディープコピーの方法
□投稿者/ howling (47回)-(2012/11/07(Wed) 12:16:51)
Jittaさん、Hongliangさん

まず、Jittaさんご返信いただきありがとうございました。

> "か"ではなく"と"ですよね?
これ、よくよく見たらその通りでした。
ファイル作らずにデータをカプセル化してくれる!やった!
くらいしか見てませんでした(苦笑

さて、この2つのキーワードを基に調べてみたのですが、
あまりにピンポイントな記事がありました。
ほぼコピペして使ってるんですが、権利とか大丈夫かな(おろおろ

「どんなオブジェクトでもコピーできる汎用のディープコピー処理」
http://d.hatena.ne.jp/tekk/20100131/1264913887

…コーディングするつもりだっただけに、唖然としました…。
ジェネリックまで作ってありますし。うーむ。

一応、今はコピー内容のチェック中です。
多分問題無いと思いますが、Serializableつけまくっただけなので、ちょっと怖い…。
NonSerializable属性は使ってません。コピーされて困る情報などない!

…というわけで、色々と情報のご提供ありがとうございました。
解決とさせて頂きます。また問題が出た時は後日お世話に(苦笑

ではでは。
解決済み
引用返信 編集キー/
■64102 / inTopicNo.7)  Re[6]: ディープコピーの方法
□投稿者/ Hongliang (16回)-(2012/11/07(Wed) 19:24:40)
2012/11/07(Wed) 19:26:18 編集(投稿者)

> NonSerializable属性は使ってません。コピーされて困る情報などない!

http://bbs.wankuma.com/index.cgi?mode=al2&namber=63975
コピーされて困る情報の例です。
// ご覧になってるとは思いますが。
解決済み
引用返信 編集キー/
■64103 / inTopicNo.8)  Re[7]: ディープコピーの方法
□投稿者/ howling (51回)-(2012/11/07(Wed) 21:39:53)
Hongliangさん

> コピーされて困る情報の例です。
> // ご覧になってるとは思いますが。

はい、さすがに私も答える側でいましたので。
今のところ特に問題ありません。
ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -