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

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

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

Re[4]: ICloneable について


(過去ログ 88 を表示中)

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

■52369 / inTopicNo.1)  ICloneable について
  
□投稿者/ SS (1回)-(2010/08/06(Fri) 19:40:08)

分類:[C#] 

VS2008 C# Framework3.5
Windows Vista


お世話になります。

クラスを値コピー出来ないかと思い、ICloneable, MemberwiseClone の
キーワードにたどり着きました。
一応、一通りネットで検索したりヘルプを見たりはしたつもりです。

で、結局理解できなかったのは、

1. ICloneable の実装と機能について?
 これは本当に初心者丸出しの質問かもしれませんが、
 ネットで検索中に良く見たソースですが、

 class Hoge : ICloneable
 {
  int aaa = 0;
 
  object ICloneable.Clone()  ←ここ※
  {
   return this.MemberwiseClone();
  }
 }

 ここ※ の指す部分は、Private や Public や Protected も
 記述できません。 もちろんクラスの外から見えません。
 (そもそも ”インターフェイス” を理解してないのかもしれません)
 結局は Public な(そしてキャストする) Clone()メソッドを用意するわけです。

  object ICloneable.Clone()  ←ここ※
  {
   return this.Clone();
  }

  Public Hoge Clone()
  {
   return (Hoge)this.MemberwiseClone();
  }

 この記述で、ICloneable はインターフェイスとして機能してるんでしょうか?
 ここ※ は、いつ流れるんでしょうか?
 このクラスを呼ぶ側の記述に何か特徴があるんでしょうか?
 ただ Hoge hg1 = new Hoge();
    Hoge hg2 = new Hoge();
    hg1.aaa = 10;
    hg2 = hg1.Clone();
 では駄目なのでしょうか?


2. ICloneable て必要?
 MenberwiseClone は ICloneable の記述なしでも動作する。
 しかしヘルプには ”ICloneableインターフェイスを実装するクラスを使用します。”
 とあるが、使用例として紹介されているソースコードには ICloneable の記述は一切無い。
 それに、DeepCopy を考えると Public な Clone() という名のだたのメソッドを
 用意してしまえば、MenberwiseClone が要らなくなり、ICloneable も要らない
 となってしまいませんか?


とりとめのない質問になってしまいましたが、
どうかよろしくお願いします。

引用返信 編集キー/
■52372 / inTopicNo.2)  Re[1]: ICloneable について
□投稿者/ Hongliang (684回)-(2010/08/06(Fri) 19:55:18)
>  この記述で、ICloneable はインターフェイスとして機能してるんでしょうか?
こういう記述を「インターフェイスの明示的実装」と呼びます。
明示的に実装されたインターフェイスのメンバを呼び出すには、そのインターフェイスにキャストしてやります。
object x = ((ICloneable)hg1).Clone();
Hoge y = ((ICloneable)hg1).Clone(); // ICloneable.Clone は返値が object なのでコンパイルエラー
Hoge z = hg1.Clone();

> 2. ICloneable て必要?
一応、インターフェイスとして用意されていることで、ICloneable を受け取るメソッドや、ジェネリックの型制約として使用することができるようになります。
ただ ICloneable は「ディープコピーなのかシャロウコピーなのか明らかでない」曖昧なインターフェイスであるという欠陥を持っているため、現在は非推奨のインターフェイスになっています。
新たに作る型に実装させることはないでしょう。共通したインターフェイスが欲しいとしても、IShallowCopy<T> とかそんな感じのインターフェイスを新しく定義してそれを実装させることになるかと思います。
引用返信 編集キー/
■52378 / inTopicNo.3)  Re[2]: ICloneable について
□投稿者/ SS (3回)-(2010/08/07(Sat) 00:04:43)
Hongliang さん、早速の返信ありがとうございます。


■No52372 (Hongliang さん) に返信

>> この記述で、ICloneable はインターフェイスとして機能してるんでしょうか?
> こういう記述を「インターフェイスの明示的実装」と呼びます。
> 明示的に実装されたインターフェイスのメンバを呼び出すには、そのインターフェイスにキャストしてやります。
> object x = ((ICloneable)hg1).Clone();
> Hoge y = ((ICloneable)hg1).Clone(); // ICloneable.Clone は返値が object なのでコンパイルエラー
> Hoge z = hg1.Clone();

なるほど、やはり呼ぶ側の記述の仕方 と言うか
やはりインターフェイスについて良く分かってなかったようです。
そうですよね、複数のクラスで Clone() メソッドを共用するための ”インターフェイス” ですもんね。
つまり、Hoge z = hg1.Clone(); のみを考えればインターフェイスは必要ない
という事でよろしいですよね?


という事は…、

>>2. ICloneable て必要?
> 一応、インターフェイスとして用意されていることで、ICloneable を受け取るメソッドや、ジェネリックの型制約として使用することができるようになります。
> ただ ICloneable は「ディープコピーなのかシャロウコピーなのか明らかでない」曖昧なインターフェイスであるという欠陥を持っているため、現在は非推奨のインターフェイスになっています。
> 新たに作る型に実装させることはないでしょう。共通したインターフェイスが欲しいとしても、IShallowCopy<T> とかそんな感じのインターフェイスを新しく定義してそれを実装させることになるかと思います。

基本的に、Clone() したいクラスのクラス内でキャストして返す 事を
機能として盛り込む事を考えると、共通のインターフェイスは使えない?
あえて ICloneable を使おうとすると、呼ぶ側でのキャストが必要になる…と。
推奨もされてないとなると、尚更使うことをためらうなぁ。

まだ ざっくりとですが、分かったような気がしてきました。
ありがとうございます。


あとは…、
> MenberwiseClone は ICloneable の記述なしでも動作する。
> (以下略)
についてはどうなんでしょうか?
MemberwiseClone() を使用するに当たって ICloneable は必須なんでしょうか?

引用返信 編集キー/
■52379 / inTopicNo.4)  Re[3]: ICloneable について
□投稿者/ Azulean (589回)-(2010/08/07(Sat) 01:06:23)
No52378 (SS さん) に返信
> つまり、Hoge z = hg1.Clone(); のみを考えればインターフェイスは必要ない
> という事でよろしいですよね?

必要ないでしょう。
Hoge クラスを返す実装があり得るのは、Hoge クラス自身かその派生クラスでしょうから、あえてインターフェースとして切り出す必要も感じません。

> あえて ICloneable を使おうとすると、呼ぶ側でのキャストが必要になる…と。
> 推奨もされてないとなると、尚更使うことをためらうなぁ。

この辺も紹介しておきます。(似たようなことが書いてあると思います)
http://blogs.msdn.com/b/brada/archive/2004/05/03/125427.aspx


> MemberwiseClone() を使用するに当たって ICloneable は必須なんでしょうか?

必要ありません。
MemberwiseClone は Object 型に用意されているメソッドなので、ICloneable との関連性はありません。
http://msdn.microsoft.com/ja-jp/library/system.object.memberwiseclone.aspx
引用返信 編集キー/
■52388 / inTopicNo.5)  Re[4]: ICloneable について
□投稿者/ SS (4回)-(2010/08/07(Sat) 17:31:32)
Azulean さん、返信ありがとうございます。

■No52379 (Azulean さん) に返信
> この辺も紹介しておきます。(似たようなことが書いてあると思います)
> http://blogs.msdn.com/b/brada/archive/2004/05/03/125427.aspx

すいません、ここへたどり着いたことはありますが、英語は読めません。
web翻訳で読んでみましたが、途中で断念しました。orz


>>MemberwiseClone() を使用するに当たって ICloneable は必須なんでしょうか?
> 
> 必要ありません。
> MemberwiseClone は Object 型に用意されているメソッドなので、ICloneable との関連性はありません。
> http://msdn.microsoft.com/ja-jp/library/system.object.memberwiseclone.aspx

私が見たのはこのヘルプです。 最後の一文の
 ICloneable インターフェイスを実装するクラスを使用して、オブジェクトの詳細コピーまたは簡易コピーを実行します。
が気になって気になって…。
詳細コピーでも簡易コピー(MemberwiseClone)でも
ICloneable を実装したクラスでなければ実行できない と思ってしまいました。

加えて、
私が最初に投稿したソースの例でも(必要なさそうなのに) ICloneable を記述していたので、
混乱してしまった次第です。


これで大分すっきりしてきました。

Hongliang さん、
Azulean さん、
ありがとうございました。

解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -