none
Bitmapの様なクラスのインスタンスをコピーするには? RRS feed

  • 質問

  • Bitmapクラスの様な、.NET付属(?)のインスタンスをコピーする方法がわからなくて困っています。

    ソースコードで説明すると
                Rectangle rec = Screen.PrimaryScreen.Bounds;
                Bitmap bmp1 = new Bitmap(rec.Width, rec.Height);
                Bitmap bmp2 = new Bitmap(rec.Width, rec.Height);
                Bitmap bmp;

                bmp = bmp1;

    この様なコードを書いているのですが、これだとbmpにはbmp1のインスタンスの参照が渡されていますよね?
    これをなんとか値を渡したいんです。

    自分で作ったクラスならICloneableインターフェイスなどを使ってCloneメソッドのようなものが実装できるようなのですが、このようなもとからある(?)クラスには実装できなくて困っています。

    @自分はまだプログラム初心者なので、すこし初心者向けの回答にしていただけると助かります。
    2009年5月13日 21:35

回答

  • この様なコードを書いているのですが、これだとbmpにはbmp1のインスタンスの参照が渡されていますよね?
    これをなんとか値を渡したいんです。
    なぜですか?
    どのようなことを実現しようとしてお困りなのでしょうか?

    自分で作ったクラスならICloneableインターフェイスなどを使ってCloneメソッドのようなものが実装できるようなのですが、このようなもとからある(?)クラスには実装できなくて困っています。
    統一的な手法はありません。
    個々のクラスに応じて、コピーするための手段をご自身で外部から実装して下さい。
    (新しいインスタンスを作って、その中に同じデータを持たせるようにメソッド・プロパティを操作する)

    なお、Bitmapクラスであれば、メンバーを眺めたら良いと思いますよ。
    http://msdn.microsoft.com/ja-jp/library/system.drawing.bitmap_members.aspx


    ところで、ICloneableはこだわる必要はありません。
    理由としては、戻り値が必ずobject型になり、戻り値を使うためにはキャストする必要があるためです。
    ICloneableを実装するよりは、独自のCloneメソッドを実装して、戻り値を具体的な型にした方が良いんじゃないかな?
    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク SE_lain 2009年5月14日 6:46
    2009年5月13日 22:24
    モデレータ

すべての返信

  • この様なコードを書いているのですが、これだとbmpにはbmp1のインスタンスの参照が渡されていますよね?
    これをなんとか値を渡したいんです。
    なぜですか?
    どのようなことを実現しようとしてお困りなのでしょうか?

    自分で作ったクラスならICloneableインターフェイスなどを使ってCloneメソッドのようなものが実装できるようなのですが、このようなもとからある(?)クラスには実装できなくて困っています。
    統一的な手法はありません。
    個々のクラスに応じて、コピーするための手段をご自身で外部から実装して下さい。
    (新しいインスタンスを作って、その中に同じデータを持たせるようにメソッド・プロパティを操作する)

    なお、Bitmapクラスであれば、メンバーを眺めたら良いと思いますよ。
    http://msdn.microsoft.com/ja-jp/library/system.drawing.bitmap_members.aspx


    ところで、ICloneableはこだわる必要はありません。
    理由としては、戻り値が必ずobject型になり、戻り値を使うためにはキャストする必要があるためです。
    ICloneableを実装するよりは、独自のCloneメソッドを実装して、戻り値を具体的な型にした方が良いんじゃないかな?
    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク SE_lain 2009年5月14日 6:46
    2009年5月13日 22:24
    モデレータ
  • お返事ありがとうございます。

    <<どのようなことを実現・・・
    実は、特定の範囲のスクリーンの画像が変わったかどうかを調べるものを作りたいとおもっているんです。そのためにbmp1とbmp2に別々の時間のスクリーンショットを保存して、それを比べることによってその機能を実装しようとおもったんですが、参照を渡してしまうと比べる元のbmp1や2も変わってしまうので値を渡したかったんです。

    <<なお、Bitmapクラスであれば・・・
    言われたとおりに眺めていたらcloneメソッドという、そのままのがあったんですね。大変お恥ずかしい限りです。おかげさまで解決できました。

    <<Cloneableを実装するよりは・・・
    この部分なのですがどうすればBitmapクラスのような、自分では作っていないクラスに独自のメソッドを追加できるのでしょうか?よろしければ教えていただけると嬉しいです。
    2009年5月14日 6:43
  • そのためにbmp1とbmp2に別々の時間のスクリーンショットを保存して、それを比べることによってその機能を実装しようとおもったんですが、参照を渡してしまうと比べる元のbmp1や2も変わってしまうので値を渡したかったんです。

    少し疑問に思ったのですが、書かれている内容からするとCloneメソッドを使わなくても、それぞれのインスタンスを保持しておいて比較すれば良いような気がします。私が理解し切れていないのかもしれませんが・・・

    <<Cloneableを実装するよりは・・・
    この部分なのですがどうすればBitmapクラスのような、自分では作っていないクラスに独自のメソッドを追加できるのでしょうか?よろしければ教えていただけると嬉しいです。

    通常は継承して独自メソッドを追加しますが、BitmapはSealedなので継承できません。したがって、委譲や拡張メソッドを使うことになるでしょう。

    Javaなんですが、C#の委譲の良いサンプルを見つけられなかったので紹介しておきます。C#を知っていれば、以下のサンプルも読めると思います。

    Deep Side of Java~Java 言語再入門 第3回 ~ クラス設計とデザインパターン
    http://www.nurs.or.jp/~sug/soft/java/java32.htm

    委譲にdelegateを使った例です。

    第13章 処理を委譲するデリゲート
    http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_013/cs2_013_01.html

    拡張メソッドの例です。

    方法 : カスタム拡張メソッドを実装して呼び出す (C# プログラミング ガイド)
    http://msdn.microsoft.com/ja-jp/library/bb311042.aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年5月14日 7:13
    モデレータ
  • 少し疑問に思ったのですが、書かれている内容からするとCloneメソッドを使わなくても、それぞれのインスタンスを保持しておいて比較すれば良いような気がします。私が理解し切れていないのかもしれませんが・・・
    そういわれるとそうですね。いろいろ検討してみます。
    通常は継承して独自メソッドを追加しますが、BitmapはSealedなので継承できません。したがって、委譲や拡張メソッドを使うことになるでしょう。
    このような方法があったのですね。参考になりました。ありがとうございます。
    2009年5月19日 4:02