- PR -

特集「私がJavaからC#に乗り換えた10の理由」について

投稿者投稿内容
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2003-07-20 14:08
反論です。

引用:
英-Ranさんの書き込み (2003-07-20 12:40) より:
では、C#のdelegateはなんでしょう。答えは、きちんとMicrosoftのドキュメントには書いていますが、

C# delegate:メソッド参照

です。C# delegateというものが実際には「bound method reference」とよばれる技術であることからもこれは明白です。yaさんはC# delegateの良さをいろいろと語ってくれましたが、書いていて「オブジェクトなら当たり前のこと」ばかり書いていたことに気付きませんでした?

# C# delegateという名称が誤解を招くという話が以下のスレッドで書かれています。
# http://java-house.jp/ml/archive/j-h-b/019913.html#body

なぜ、C# delegeteにはdelegateオブジェクトのようなラッピングを必要とするのか。
それはC# delegateの本質がメソッド参照(悪く言えば関数ポインタ)だからです。



まず言葉の確認からしたいのですが、「メソッド参照」とは、「あるクラスのあるメソッド」を参照することなのか、「あるインスタンスのあるメソッド」を参照することなのか、どちらになるのでしょうか? 前者は関数ポインタのみで表現可能なのですが、後者は関数ポインタだけでは表現不可能です。
関数ポインタという言葉がでたところからして「メソッド参照」という言葉は前者の「あるクラスのあるメソッド」であると思われるのですが、そうだとするとdelegateの説明は正しくありません。正しくは、

C# delegate:メソッド参照 & 委譲先のインスタンスへの参照

と、なります。(私の書いたJavaScript版Delegateクラスでいえば、Delegate.Targetの有無の違いになります)

あと、これは余計なお節介なのですが、Microsoftのドキュメントを当てにしすぎるのは危険です。実際、SDKのヘルプにも Delegate の説明について、きちんと説明されていない誤解を招きやすい表現(それこそ関数ポインタとしか思えなくなるような)が、かなりありますので……(Microsoft提唱の言語なのに、というつっこみはなしの方向で(汗))
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-20 16:16
引用:

k-nakさんの書き込み (2003-07-20 14:08) より:
まず言葉の確認からしたいのですが、「メソッド参照」とは、「あるクラスのあるメソッド」を参照することなのか、「あるインスタンスのあるメソッド」を参照することなのか、どちらになるのでしょうか? 前者は関数ポインタのみで表現可能なのですが、後者は関数ポインタだけでは表現不可能です。



とりあえず、その問題はおいておいてください。それは委譲処理で扱うコンテキストをどうするかという非常に難しい問題に関わってきます(で、委譲とは直接関係する話題なのだけど切り離して議論できる問題でもある)。

引用:

あと、これは余計なお節介なのですが、Microsoftのドキュメントを当てにしすぎるのは危険です。実際、SDKのヘルプにも Delegate の説明について、きちんと説明されていない誤解を招きやすい表現(それこそ関数ポインタとしか思えなくなるような)が、かなりありますので……(Microsoft提唱の言語なのに、というつっこみはなしの方向で(汗))



この問題に関しては、Microsoftの言い分の方が正しいのです。技術的にはC# delegateというのは明確に「関数ポインタみたいなもの」です。それを理解せずしては、なぜJavaHouseの高木さんがあんなにお怒りなのかは理解できません。

(以下、無駄話)
もし、C#で「C# delegate」ではなく「メソッドオブジェクト」が採用されていたとして、私が「C# delegate」の方がいいのではと主張したとしても、yaさんやobjectさん、catsさんは「C# delegate」の方がいいことに賛同しただろうか。

おじまさんが、「メソッドオブジェクトの採用がJavaに対する利点である」と主張するであろう事は容易に想像できるけれど
Izumi, Y.
ベテラン
会議室デビュー日: 2002/03/19
投稿数: 77
お住まい・勤務地: 東京
投稿日時: 2003-07-20 16:26
引用:

k-nakさんの書き込み (2003-07-20 14:08) より:
まず言葉の確認からしたいのですが、「メソッド参照」とは、「あるクラスのあるメソッド」を参照することなのか、「あるインスタンスのあるメソッド」を参照することなのか、どちらになるのでしょうか?


後者にとるべきでは?
具体的には、インスタンス自身に含まれるメソッド(かそれに該当するもの)を参照するのではないかと。「関数」という言葉は、普通はオブジェクト指向でない言語の話をするときに使用する言葉なので、「関数ポインタ」はメソッド参照によく似た(あるいは本質的な考え方は同じ)概念を表す用語として持ち出したのだと思います。
より厳密には、static なメソッドは前者、static でないメソッドは後者になると思いますが(なんか static の定義を述べているみたいになりますね)。
Izumi, Y.
ベテラン
会議室デビュー日: 2002/03/19
投稿数: 77
お住まい・勤務地: 東京
投稿日時: 2003-07-20 16:28
のんびり書いていたらかぶってしまいました。
英-Ran さんによれば難しい話になるようなので、すぐ上の書き込みにはこれ以上関わらない方針で (^^;
nak2k
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 86
投稿日時: 2003-07-20 17:59
IZUMI様感謝。私の発言で誤解を招きやすい箇所がわかりました。

私の発言の「あるクラスのあるメソッド」は「クラスメソッド(staticメソッド)」を意図していたわけではなく、「リフレクションのメソッドオブジェクト」=「非staticなメンバ関数へのポインタ」のことを指していたのです。

私にはどうしても「メソッド参照」という言葉の定義が「リフレクションのメソッドオブジェクト」と「あるインスタンスのあるメソッドへの参照」との間で揺れ動いていたように思えましたので、そのための確認だったのです。

引用:
英-Ranさんの書き込み (2003-07-20 16:16) より:
とりあえず、その問題はおいておいてください。それは委譲処理で扱うコンテキストをどうするかという非常に難しい問題に関わってきます(で、委譲とは直接関係する話題なのだけど切り離して議論できる問題でもある)。



C#のdelegateにおけるコンテキスト解決は以下のようになります。

「あるインスタンスのあるメソッド」に対するデリゲートの場合は、デリゲート自身が”委譲先インスタンスへの参照”と”委譲先メソッドへの参照(=リフレクションのメソッドオブジェクト=メンバ関数ポインタ)”を保持しておりますので、委譲先インスタンスのコンテキストで委譲先メソッドを呼び出します。

「あるクラスのあるメソッド(staticメソッド)」に対するデリゲートの場合は、”委譲先インスタンスへの参照”はnull参照になっており、委譲先メソッドへの参照のみで、委譲先メソッドの所属するクラスオブジェクトのコンテキストで、委譲先メソッドが呼び出されます。(メソッド参照があれば、該当するクラスオブジェクトはリフレクションにより取得可能ですし)
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-20 19:07
ALL >
宜しければ、後学のために教えていただけたら有難いのですが、委譲処理は
C# がメソッド参照、Javaがオブジェクトであるというのは、C#がDLLの上に
構築されているのに対し、JavaはVMという座布団の上にある、という構造上の
違いに起因しているからでしょうか?
(というのは委譲の本質は、言語側にあるのではなくシステム側から投げられるという
仮説があるからなのですが。)よろしければご教授お願いします。


[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-07-20 19:08 ]
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-20 19:32
引用:

Ken-Labさんの書き込み (2003-07-20 19:07) より:
ALL >
宜しければ、後学のために教えていただけたら有難いのですが、委譲処理は
C# がメソッド参照、Javaがオブジェクトであるというのは、C#がDLLの上に
構築されているのに対し、JavaはVMという座布団の上にある、という構造上の
違いに起因しているからでしょうか?
(というのは委譲の本質は、言語側にあるのではなくシステム側から投げられるという
仮説があるからなのですが。)よろしければご教授お願いします。



C言語のqsort関数だって委譲を使うわけだから、システムとは関係ないと思いますが……
C#のCLIってJava VMと同じ役割を果たすものだと私は認識していたのですが、もしかして違うのかな?

委譲処理でC#ではメソッド参照、Javaでは無名InnerClassなのは、技術的な問題というより政治上の問題だと私は認識しています。

良い悪いは別として、Microsoftの意図は以下の高木さんの発言に集約されているんでしょうね。(以下の文はVisual J++に対して書かれたものですので誤解なきよう。念のため)
引用:

Java言語を理解していない人にとってわかりにくいからといって、
安易な独自仕様に走る Microsoft は相変わらず他の製品同様、
「unsophisiticated peopleに媚びた設計」をし続けていますね。



http://java-house.jp/ml/archive/j-h-b/019785.html#bodyより引用

[ メッセージ編集済み 編集者: 英-Ran 編集日時 2003-07-20 20:29 ]
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-20 19:38
引用:

k-nakさんの書き込み (2003-07-20 17:59) より:
C#のdelegateにおけるコンテキスト解決は以下のようになります。



分かりやすい解説ありがとうございます。
うーむ、それってプログラマは楽だけど、メモリリークの原因になったりしないんだろうか。

スキルアップ/キャリアアップ(JOB@IT)