- - PR -
特集「私がJavaからC#に乗り換えた10の理由」について
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-07-16 21:11
ご明察。C#のドキュメントにはきちんと書いてありますが、delegateで定義したオブジェクトは単なる「メソッド参照のラッパーオブジェクト」で、実体は「target.handler」の方です。型が付いているように見えるのはみかけだけです。
そろそろ、Javaの無名InnerClassの設計がいかによく考えられたものであるかということに気付きませんか?
objectさんは、無名InnerClassだけでなく、C#のdelegateもきちんと理解できていないと思われますので、そのような発言は慎んだほうがよろしいかと思います。 [ メッセージ編集済み 編集者: 英-Ran 編集日時 2003-07-16 21:12 ] | ||||||||||||||||
|
投稿日時: 2003-07-16 21:34
楽しみにしております。 | ||||||||||||||||
|
投稿日時: 2003-07-16 22:38
| ||||||||||||||||
|
投稿日時: 2003-07-16 23:45
inner class vs delegateな話がちょっと出ていますが、
J++の頃にも色々な議論があったので、参考になるのではないでしょうか? http://java-house.jp/ml/archive/j-h-b/020252.html delegate自体は、ラッパークラス作成マクロみたいなもので、 コンパイラがチェックしてくれる分、楽だという面と、 わざわざ言語の一部で取り込むようなものだろうか?という面がありますね。 C#は哲学で言うところのプラグマティズム(実用主義)って感じなのかな? | ||||||||||||||||
|
投稿日時: 2003-07-16 23:52
記事へのツッコミです。
- 理由06 - interface 個人的に尾島氏が挙げている例は間が抜けていると思われます。「嘆かわしい」というほどコンパイル時の型検査が必要なら public class MyClass implements Comparable{ // このメソッドは Comparable とは関係ない。 public int compareToMyClass(MyClass myClass) { /* 比較するコードは省略 */ } public int compareTo(Object obj) { return compareToMyClass((MyClass)obj); } } とでもすれば良いと思うんですが。上記の例でも尾島氏の例でも Comparable や IComparable としてはコンパイル時の型検査ができていないという意味では同等ですし。 - 理由08 - #if デバッグ用途限定という事であれば J2SE 1.4 から assert が使えるようになっていますね。 [ メッセージ編集済み 編集者: お犬様 編集日時 2003-07-17 00:59 ] | ||||||||||||||||
|
投稿日時: 2003-07-17 00:00
ども、突っ込み感謝です。
確かにそうですね。型を考えると説明しやすいかも。 つまり、delegateというのは以前に書いたとおりclassやstructと同等レベルの「型」という概念を持ち、型システムに組み込まれているものなんです。そしてシステム固定ではなく(つまりvoid Method()とかみたいな型があらかじめ決められてそれが固定的に割り当てられるのではなく)、自分で定義でき、拡張可能なんです(それもオブジェクト指向的に)。 そして、型システムに組み込まれることによって.NETにおける強力な型システムの機能を利用する事ができます。
上のコードは.NETの型システムの機能の一部です。他にも所属アセンブリの取得とか数え上げればきりがないので、その辺は省略させていただきますが。 では、delegateオブジェクトとは具体的になんなのか。大雑把に言ってdelegateオブジェクトというのは自分から型情報が参照できるメソッドを委譲するための新規オブジェクト、とでも言えばいいのかもしれません。委譲するために新規にそれを意味するオブジェクトを作ってそれを渡す(つまりイベント登録等)わけです。delegate型は内部状態に「どのメソッドを呼び出せばよいか」を持っていて通知によりそれを呼び出す(リダイレクトする)オブジェクトであってけっして「そのメソッドそのもの」ではないわけです。メソッドに関連付けられてはいますが、それぞれ独立です。 ただ、ここでもう一つの議論があるんです。つまり、「そのオブジェクトはクラスとして作ることはできないか」ということです。結論から言えば現在の.NETのclassでは普通の方法ではできません(と思います)。根拠の一つとしてアクセス権の問題を挙げたいと思います。 委譲を考えてみると、委譲する段階でアクセス権チェックが本来できればよい(つまり委譲するものがそのメソッドへの参照を許可されていれば委譲してよい)わけで呼び出されるときにアクセス権チェックなんて要らないわけです。クラスのメソッドは呼び出すときのアクセス権チェックなわけでメソッドでは実現できません。 これはまさしくdelegate型で、その例は私の前回のコードを参照してみてください。ちなみに「チェックがなくなる」なんていうと「カプセル化が壊れるんじゃ…」って思う人がいるかもしれませんが、逆です。publicにしなくてもよくなるので逆に強くカプセル化できます。 さて、色々と反論を。 >>一郎さん 型に拡張したことによって、例えばAttributeをつけることができます。これは重要な事でそれらをクラス作成者が宣言できるということが大きいのです(それはこのイベントを実装したものがこのdelegateのみを参照してこれによって縛られている事のみを考慮して作ればよいということです)。 ちなみにメソッドの型付けですが、「〜アセンブリの〜クラスに所属している〜メソッド」というように型(?)だけなら既にあります。メソッドを書いた時点でそれが定義ですし。で、問題はパラメータと戻り値が同じならば人間は共通点を見つけるわけで、これはオブジェクト指向的に言うと同じ型から派生したものだと考える事ができるわけですが、しかしC#にはそれはない(delegateとは別物)。これはそれが型の発散を招く(つまり望ましくない)からだと思うのですが。 ちなみに型としてくくらなくても(めんどくさいですが)ダイナミック型システムで解析して同じように扱う事は可能です(それで十分かなと)。 >>ほむらさん 関数ポインタとつかい方及び動作がそっくりなので関数ポインタと説明すると楽なんですが、根本的に(概念は)「違うもの」です。関数ポインタは関数への参照そのものですが、delegateは関数への通知(リダイレクト)を実現するオブジェクト指向に乗っ取った型を持った(定義できる)オブジェクトです。C++で実現するならclassを使い、関数ポインタはそのオブジェクトの中でのみ使用されるものとなります。 では、突っ込みよろしくお願いします。 [ メッセージ編集済み 編集者: ya 編集日時 2003-07-17 01:06 ] | ||||||||||||||||
|
投稿日時: 2003-07-17 08:56
明確に違います。そう思っているのであれば、yaさんはdelegateをまったく理解できていないということです。 【参考】http://java-house.jp/ml/archive/j-h-b/019802.html#body | ||||||||||||||||
|
投稿日時: 2003-07-17 09:10
ここの議論には一切関わるつもりはなかったのですが、1つだけ疑問があるので、今回だけ。
とありますが、この記述は相当古いうえ、 >Visual J++ 6.0 を動かす環境がないので確認ができないのですが (どなたか …… >されるのではないかと予想します。 と書かれていますけど、この内容は合っているのでしょうか? また、現在のC#でも、そのまま当てはまっているのでしょうか? |