- - PR -
特集「私がJavaからC#に乗り換えた10の理由」について
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-07-20 14:08
反論です。
まず言葉の確認からしたいのですが、「メソッド参照」とは、「あるクラスのあるメソッド」を参照することなのか、「あるインスタンスのあるメソッド」を参照することなのか、どちらになるのでしょうか? 前者は関数ポインタのみで表現可能なのですが、後者は関数ポインタだけでは表現不可能です。 関数ポインタという言葉がでたところからして「メソッド参照」という言葉は前者の「あるクラスのあるメソッド」であると思われるのですが、そうだとするとdelegateの説明は正しくありません。正しくは、 C# delegate:メソッド参照 & 委譲先のインスタンスへの参照 と、なります。(私の書いたJavaScript版Delegateクラスでいえば、Delegate.Targetの有無の違いになります) あと、これは余計なお節介なのですが、Microsoftのドキュメントを当てにしすぎるのは危険です。実際、SDKのヘルプにも Delegate の説明について、きちんと説明されていない誤解を招きやすい表現(それこそ関数ポインタとしか思えなくなるような)が、かなりありますので……(Microsoft提唱の言語なのに、というつっこみはなしの方向で(汗)) | ||||||||
|
投稿日時: 2003-07-20 16:16
とりあえず、その問題はおいておいてください。それは委譲処理で扱うコンテキストをどうするかという非常に難しい問題に関わってきます(で、委譲とは直接関係する話題なのだけど切り離して議論できる問題でもある)。
この問題に関しては、Microsoftの言い分の方が正しいのです。技術的にはC# delegateというのは明確に「関数ポインタみたいなもの」です。それを理解せずしては、なぜJavaHouseの高木さんがあんなにお怒りなのかは理解できません。 (以下、無駄話) もし、C#で「C# delegate」ではなく「メソッドオブジェクト」が採用されていたとして、私が「C# delegate」の方がいいのではと主張したとしても、yaさんやobjectさん、catsさんは「C# delegate」の方がいいことに賛同しただろうか。 おじまさんが、「メソッドオブジェクトの採用がJavaに対する利点である」と主張するであろう事は容易に想像できるけれど | ||||||||
|
投稿日時: 2003-07-20 16:26
後者にとるべきでは? 具体的には、インスタンス自身に含まれるメソッド(かそれに該当するもの)を参照するのではないかと。「関数」という言葉は、普通はオブジェクト指向でない言語の話をするときに使用する言葉なので、「関数ポインタ」はメソッド参照によく似た(あるいは本質的な考え方は同じ)概念を表す用語として持ち出したのだと思います。 より厳密には、static なメソッドは前者、static でないメソッドは後者になると思いますが(なんか static の定義を述べているみたいになりますね)。 | ||||||||
|
投稿日時: 2003-07-20 16:28
のんびり書いていたらかぶってしまいました。
英-Ran さんによれば難しい話になるようなので、すぐ上の書き込みにはこれ以上関わらない方針で (^^; | ||||||||
|
投稿日時: 2003-07-20 17:59
IZUMI様感謝。私の発言で誤解を招きやすい箇所がわかりました。
私の発言の「あるクラスのあるメソッド」は「クラスメソッド(staticメソッド)」を意図していたわけではなく、「リフレクションのメソッドオブジェクト」=「非staticなメンバ関数へのポインタ」のことを指していたのです。 私にはどうしても「メソッド参照」という言葉の定義が「リフレクションのメソッドオブジェクト」と「あるインスタンスのあるメソッドへの参照」との間で揺れ動いていたように思えましたので、そのための確認だったのです。
C#のdelegateにおけるコンテキスト解決は以下のようになります。 「あるインスタンスのあるメソッド」に対するデリゲートの場合は、デリゲート自身が”委譲先インスタンスへの参照”と”委譲先メソッドへの参照(=リフレクションのメソッドオブジェクト=メンバ関数ポインタ)”を保持しておりますので、委譲先インスタンスのコンテキストで委譲先メソッドを呼び出します。 「あるクラスのあるメソッド(staticメソッド)」に対するデリゲートの場合は、”委譲先インスタンスへの参照”はnull参照になっており、委譲先メソッドへの参照のみで、委譲先メソッドの所属するクラスオブジェクトのコンテキストで、委譲先メソッドが呼び出されます。(メソッド参照があれば、該当するクラスオブジェクトはリフレクションにより取得可能ですし) | ||||||||
|
投稿日時: 2003-07-20 19:07
ALL >
宜しければ、後学のために教えていただけたら有難いのですが、委譲処理は C# がメソッド参照、Javaがオブジェクトであるというのは、C#がDLLの上に 構築されているのに対し、JavaはVMという座布団の上にある、という構造上の 違いに起因しているからでしょうか? (というのは委譲の本質は、言語側にあるのではなくシステム側から投げられるという 仮説があるからなのですが。)よろしければご教授お願いします。 [ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-07-20 19:08 ] | ||||||||
|
投稿日時: 2003-07-20 19:32
C言語のqsort関数だって委譲を使うわけだから、システムとは関係ないと思いますが…… C#のCLIってJava VMと同じ役割を果たすものだと私は認識していたのですが、もしかして違うのかな? 委譲処理でC#ではメソッド参照、Javaでは無名InnerClassなのは、技術的な問題というより政治上の問題だと私は認識しています。 良い悪いは別として、Microsoftの意図は以下の高木さんの発言に集約されているんでしょうね。(以下の文はVisual J++に対して書かれたものですので誤解なきよう。念のため)
http://java-house.jp/ml/archive/j-h-b/019785.html#bodyより引用 [ メッセージ編集済み 編集者: 英-Ran 編集日時 2003-07-20 20:29 ] | ||||||||
|
投稿日時: 2003-07-20 19:38
分かりやすい解説ありがとうございます。 うーむ、それってプログラマは楽だけど、メモリリークの原因になったりしないんだろうか。 |