- PR -

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

投稿者投稿内容
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-07-17 19:25
>> いのつちさん
引用:

「インターフェイスを使えば実現できる。(またはすべきである)」
と、
(delegateがなければ)
「インターフェイスを定義して複数のクラスに分けて実装せざる得ない。」

の違いで後者の場合にdelegateを採用するという
使い分けもありかもしれません。


無名インナークラスの無いC#ではそれもありかもしれませんね。
でも、多くの実装クラスと多くの委譲先メソッドは大差ないと思います。

>> yaさん
引用:

・静的メソッドを使用して指定の実装を行う場合
・イベントに似たデザインパターンで作成する場合
・メソッドが定義されているオブジェクトが、呼び出し元と無関係の場合
この辺、インターフェイスでは難しい、またはdelegateの方が優れた実装ができるかな、と思ったり。


うーん。難しいことは何も無いと思うんだけどなー。
実装メソッドから静的メソッドを呼び出すより、デリゲートに直接指定するほうが直感的かもしれませんが…。

2つめやつは、イベントに+=してマルチキャストをしたいならそうするべきですよね。
#そりゃ言語がそう設計されているのだもの。でもその設計が絶対必要なものかは?です。
ところで、マルチキャストじゃなくて別の、例えばユニキャストや待ち行列的なイベント通知などを
したくなったらどうするんでしょう?

やっぱりデリゲートはインターフェースを専用特化させたものでしかないのでは?
お犬様
ベテラン
会議室デビュー日: 2003/01/26
投稿数: 67
投稿日時: 2003-07-17 21:43
引用:
ほむらさんの書き込み (2003-07-17 14:50) より:

なので、プリミティブな型(int等)同様 参照型も苦し紛れに導入されたものとばかり(ぉぃ

今のところ Java にはプリミティブ型と参照型しかないですが???

引用:
ほむらさんの書き込み (2003-07-17 14:50) より:

2.可読性を低下させる要因とされているgoto文の削除 (個人的にはgoto文大好きです(笑 )

Java では goto が削除された代わりにbreakcontinue が強化されてます。C# でもswitch statement内での fall through が禁止される代わりに switch 内の case や default への goto が追加されたりしていますね。

引用:
ほむらさんの書き込み (2003-07-17 14:50) より:

3.プログラマにメモリ管理を意識させない。
4.同じくメモリリークの原因となるポインタの削除

buffer over run を防止するためにポインタ演算を削除し 代わりに範囲を持った配列が導入された事、ガベージコレクタの導入された事によりメモリ管理は楽になりましたが、「メモリ管理を意識させない」と言うほどでは無いような気もします。


delegate に関して気づいた点
  • class MyDelegate : System.Delegate できない。
  • SampleEvent1Handler のコンストラクタは Void .ctor(System.Object, IntPtr) だけしかないのに new SampleEvent1Handler(m.listenClass1SampleEvent1) という記述ができる。
  • delegate MyDelegate(); のインスタンスに myDelegateInstance.Invoke(); が許されていない。
  • Clone() での複製生成や、プロパティ Target による対象オブジェクトへのアクセスが public になってるのは拙いような気がする。


[ メッセージ編集済み 編集者: お犬様 編集日時 2003-07-17 22:02 ]
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-17 22:26
引用:

yaさんの書き込み (2003-07-17 16:42) より:
>>英-Ranさん
「理解していない」とおっしゃるのなら今後のためにできればご教授願います。
自分が間違っているのならそれを正したいし、また違う側面があるならそれを学習したいです。



yaさんは、C#のdelegateはどのように使われるのかは理解されていると思いますが、言語にどのような形で委譲を導入すべきかということを考えるときはそれでは、不十分なのです。委譲の概念を実現するためにはいくつかの方法があり、それらは言語設計者なら皆知っていることです。それらの方法を比較検討し得失を知った上で、本当にC#の(現在の)delegateで良かったどうかのかどうかを考える必要があります。

とりあえず、以下の二つを説明してみてください。

・「委譲」の目的は何か
・「C# delegate」、「メソッドオブジェクト」、「無名InnerClass」のそれぞれにおいて「委譲」の主体は何か

二つ目の部分が正しく説明できれば、yaさんの言っていたことが本質を著しくはずしていることがわかるはずです。

引用:

objectさんの書き込みより:
「議論がかみ合っていない」様に見えるのは、英-Ranさんが引用だけで議論し、何かあると直ぐに個人攻撃をして、まともに話をしようとしないからだと思います。



私は、技術の話には技術の話で答えますが、失礼な発言には失礼な発言で返します。ただ、それだけのことです。

引用:

私は「オブジェクト指向」は、まだまだスタートしたばかりだと思っています。
その中で、「Class」は抽象データ型を記述する為の、最も原始的で、しかも単なる手段だと思っています。
「Class」至上主義で、「Class」の殻から出ない事に一番の価値を見出している限り、「Class」を超える新しい概念も出て来ないと思います。
実際、この様な場でも本音の議論が出来ないですよね。



オブジェクト指向が生まれてからもう30年以上経つのですが? 何も知らないくせに、知ったかぶりをして発言をしないでください。オブジェクト指向を批判するのであれば、あなたの天才的な頭脳を駆使して、それを上回る概念を提出してください。出してくれるなら、それに関しておおいに議論しましょう。

[ メッセージ編集済み 編集者: 英-Ran 編集日時 2003-07-17 22:28 ]
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2003-07-17 23:01
こんばんは、meiです。

収束するかに思えたスレッドですが、更に伸びていますね。

引用:

・「委譲」の目的は何か
・「C# delegate」、「メソッドオブジェクト」、「無名InnerClass」のそれぞれにおいて「委譲」の主体は何か



オブジェクト指向における再利用の主要は手法として、
継承とオブジェクトコンポジションがありますが、
委譲はオブジェクトコンポジションとしての技法の一つですよね。

継承は新しく部品を作るのに効果的ですが、
コンポジションは部品の合成に力を発揮します。
デザインパターンでもコンポジションは結構使われていますよね。

StateとかStrategyとかVisitorとか、
Chain of Responsibilityなんかはその名の通りですし。

個人的には委譲って言語というよりも、
デザインパターンの文脈の方がしっくりと来たりします。
なので、クラスがあれば委譲は実現可能だと思います。

そもそも、C#のdelegateはやっていることは、
クラスを使った普通の委譲で、言語としての新しい要素ではなく、
手作業を減らすRAD機能に近いと思います。

Javaは本職じゃないので自信がないのですが、
inner classってC#のdelegateと同レベルで比較するものではない気がしますが、
どうなんでしょうか?

委譲のためだけに持ち込んだ概念だとすると、
ちょっと大がかりかなとか思えるし。


[ メッセージ編集済み 編集者: mei 編集日時 2003-07-18 00:26 ]
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-17 23:05
引用:

meiさんの書き込み (2003-07-17 23:01) より:

オブジェクト指向における再利用の主要は手法として、
継承とオブジェクトコンポジションがありますが、
委譲はオブジェクトコンポジションとしての技法の一つですよね。



この答えではダメなのです。これは方法であって目的ではないのです。これが正しく答えられないから、、

引用:

inner classってC#のdelegateと同レベルで比較するものではない気がしますが、
どうなんでしょうか?



という誤解がとけないのです。
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2003-07-17 23:53
ども、meiです。

引用:

英-Ranさんの書き込み (2003-07-17 23:05) より:

この答えではダメなのです。これは方法であって目的ではないのです。これが正しく答えられないから、、



あれれ、目的になってないですか(汗)。
目的はオブジェクトの再利用というつもりだったのですが・・・

イメージ的にはクラス間の関係が継承は密で、委譲は粗ですよね。

-- 削除
Javaのinnerクラスを勘違いしていたのでバッサリ削除。
てっきりMix-inっぽいことするものだと思ってました(汗)。
--

考え方の違いかも知れませんが、
私は移譲先は全然無関係なクラス(例えば汎用的なサービスクラス)とかで
全然構わないと思っています。

一歩間違えると分かり難くなるかも知れませんが、
個人的には、C#のdelegateくらいなら、
使ってて訳が分からなくなることは無いとか思ってたりして(笑)。


[ メッセージ編集済み 編集者: mei 編集日時 2003-07-19 01:45 ]
とめ
会議室デビュー日: 2003/07/17
投稿数: 1
投稿日時: 2003-07-18 00:08
#私もこの熱いスレッドに思わずつられて入会してしまいました。
#少し新しい風を吹かせるのに挑戦しようかと...

C#におけるdelegateですが、ジェネリックプログラミングにおける
関数オブジェクト(ファンクタ)との対比ってのはいかがでしょうか。

C++だと、オペレータオーバーロードで
class minusOperation
{
public:
int operator(int a, int b) const
{
return a-b;
}
};

class customMinusOperation
{
public:
int operator(int a, int b) const
{
return a-b*2;
}
};

void useFunctor()
{
minusOperation minusOp;
int result = minusOp(2, 1);
customMinusOperation minusOp2;
int result2 = minusOp2(2, 1);
}

こんなかんじになりますけど、これよりはC#のdelegateのほうが
柔軟性が高いと思いますがいかがでしょうか。

public delegate int MinusOperation(int a, int b);

class MyClass
{
private int myMinusMethod(int a, int b)
{
return a-b;
}
private int myCustomMinusMethod(int a, int b)
{
return a-b*2;
}

public void useDelegate()
{
MinusOperation minusOp = new MinusOperation(this.myMinusMethod);
int result = minusOp(2, 1);
MinusOperation minusOp2 = new MinusOperation(this.myCustomMinusMethod);
int result2 = minusOp2(2, 1);
}
}

Javaだとどのように実現するのか興味があります。やはりインタフェース


interface minusOperatable {
void setArgument(int a, int b);
void calculate();
int getResult();
}
class myMinusOperation implements minusOperatable
{
// 省略
}

ってこれは、やりすぎですよね。どなたか識者の方お願いします。

#新しい油にならないよう祈りつつ...
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-18 00:40
引用:

meiさんの書き込み (2003-07-17 23:53) より:
あれれ、目的になってないですか(汗)。
目的はオブジェクトの再利用というつもりだったのですが・・・



難しく考えすぎですよ。それに、オブジェクト指向というものそのものがひとつの手段ですから、委譲の目的を考える上ではオブジェクト指向は無視しちゃってかまいません。

引用:

一郎さんの書き込みより:
「型の発散を招く」というのも分かりました。想像してみましたが、確かに面倒くさくなりそうです。



なんだか、流れすぎて見過ごすところでしたが、これがメソッドオブジェクトに関するものであれば、型の発散は起こりません(理由は、配列型が発散しないのと同じです)。

また、無名InnerClassを使うとオブジェクトが発散するが、delegateを使えば発散しないという議論もありましたが、そうではないということが以下で述べられています。

http://java-house.jp/ml/archive/j-h-b/019868.html#body

まあ、これはきちんと各委譲の実現方法を比べてやれば自明な話なんですが(結局のところ、書かなきゃならないことはやはりどこかに書いてなきゃならないのです)。

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