- PR -

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

投稿者投稿内容
アイティメディア藤村
@ITスタッフ
会議室デビュー日: 2001/07/27
投稿数: 244
お住まい・勤務地: 飯能<->丸の内
投稿日時: 2003-07-19 13:58
藤村@管理者ではありませんが...です。

「掲示板から削除」云々という発言がお二方から挙げられています。
このスレッドに止まらず、長く@ITやその会議室をご覧になられている方はご存知のように、私どもは@ITへの非難も含めて投稿意見の強制的な削除はしてきていません。

このスレッドは、そもそもJavaとC#の「言語」論的な相違や優位性議論から始まったものですが、その議論の健全な発展に注目している方々が多く見守っています。その文脈も含めて個人的な非難(理解している、していない)に陥って停滞してはもったいないと思います。

ことはすでにJavaとC#の対比議論に止まらず、オブジェクト指向言語やその技術に熱い関心を寄せ、ソフト開発のあり方を高めていきたいという人々にとって、フォーラムや会議室の違いも超えて議論が交わされる得がたい場になっているものと思います。
この点、お二人も含めて皆さんにとても感謝しています! ぜひ完備した情報としてこのスレッドを残していきましょう。削除なんてもったいない。

個人にフォーカスした応酬で貴重な議論が見えにくくなるようなことは避けたいと強く願います。

最近の法令解釈では、係争ともなれば投稿された情報の撤回や投稿者情報の提示などがホスト側に求められる流れにありますが、私どもアットマーク・アイティがそのような振る舞いをしなくてよいように、お互いに自制しましょう。見守られている方々もご協力お願いいたします。

[ メッセージ編集済み 編集者: アットマーク・アイティ藤村 編集日時 2003-07-19 14:01 ]
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2003-07-19 14:06
引用:

引用:

これから分かる様に、(c)の形式、つまり「メソッドシグニチャ」で直接「イベント」の定義をしたとしても、メソッドの引数にさえ出来ないという中途半端な状態になります。



なぜ出来ないのです? Methodオブジェクトはfirst Class Objectですよ。



お二人の言っていることって、

objectさん:(型チェックがされた形では)メソッドの引数に出来ない。
英-Ranさん:Method型として渡せる。(型チェックには言及していない)
#ここでの型チェックってメソッドのシグネチャのチェックです。念のため。

って、事じゃないですか?

objectさんの次に続く文章を読んでいくと、
コンパイル時に型チェックさせようという意図が読みとれるので、
議論としてはコンパイル時チェックvs実行時チェックになるのでは・・・

私はpythonやrubyなど型チェックの厳しくない言語より、
型チェックの厳しい言語になれているので、
出来るだけコンパイル時にチェックされるようにしないと不安です。


[ メッセージ編集済み 編集者: mei 編集日時 2003-07-19 14:10 ]

[ メッセージ編集済み 編集者: mei 編集日時 2003-07-19 14:22 ]
樋口/@IT
@ITスタッフ
会議室デビュー日: 2001/07/26
投稿数: 293
お住まい・勤務地: 東京都
投稿日時: 2003-07-19 14:21
みなさま、活発なディスカッション、ありがとうございます。

この会議室の運営者の基本的なスタンスは、会議室のトップページにもありますとおり、「@IT会議室への書き込みの内容については、それぞれの投稿者の方が責任をお持ち@IT会議室への書き込みの内容については、それぞれの投稿者の方が責任をお持ちください」です。
投稿者のみなさんに責任をお持ちいただくと同時に、私どもは書き込みの内容についての干渉はできる限りしないようにさせていただいており、法令の定めなどによる措置を除いては、個々の書き込みの編集や削除は私どもでは行いません。

従いまして、まことに申し訳ないのですが、
引用:

この様な技術的議論の内容から逸脱した、個人を非難する文章は
「本人に謝罪をさせ、その後訂正・削除」
をして頂きたく、ここの編集者に要求します。(これ以外にも存在します。)


というご要望にはお答えいたしかねますし、
引用:

ここの会議室への書き込みは@ITさまの著作物になるそうですので、もしも客観的に見て私の書き込みに問題があると思われるのならば削除していただいてかまいません。

ただ、削除するのであればこの会議室で私の発言した内容すべてを削除するようお願いします


というようなこともいたしません。あしからずご了承ください。

書き込まれた内容を削除したり編集したりという直接の手出しはいたしませんが、運営する立場の者として、お願いがあります。
ご存知の通り、オンラインでのディスカッションは、えてして書き込まれた内容への批判・非難と個人への批判・非難がないまぜになってしまったり、顔が見えない相手に対して、普通のface-to-faceのやりとりでは言わないような失礼なテキストを投げつけてしまったりして、極端に感情的になってしまうことがあります。
どうか、画面とキーボードの向こうには、生身の普通の人間がいるのだということを忘れずに、良識ある行動をお取りいただけますよう、皆さんにお願いいたします。

普通に社会で生活しているときと同じように、フツーの人間関係を営むためのあたりまえの気遣いを、オンラインでも。
自分の書き込んだ内容については、各自が最後まで責任を持って。

よろしくお願いします。
_________________
樋口 理
株式会社アットマーク・アイティ
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-19 14:27
引用:

meiさんの書き込み (2003-07-19 14:06) より:
英-Ranさん:Method型として渡せる。(型チェックには言及していない)



これが本当ならば、配列型(例えばString[]型)の型チェックが行われないということになってしまいますね。メソッドオブジェクトを採用する場合、型チェックつけた状態で言語仕様に持ち込むのは当然です。

# という話がソースコードから読み取れなかったのなら申し訳ない

(追記:読み返してみるとわかりにくいような気がするので補足します。私は、Methodオブジェクトを使う言語でまともにプログラミングをしたことはないので、特にrubistの人で間違っていると思う部分があれば訂正してください)

Methodオブジェクトの考え方は「メソッドもオブジェクトである」ということです。JavaScriptのFunctionオブジェクトを使ったことのあるかたならある程度想像がつくかと思いますが、Methodオブジェクトが存在する言語では以下のfakeコードは同義です(本当は処理内容の定義が必要だが、ここでは訳あって省略)。

public void hogehoge(int a, object b);
public final Method(void, int, object) hogehoge = new Method(void, int, object);

ここまで認めてしまえば、hogehogeは単なる「Method(void, int, object)型のオブジェクト」ですので、
コード:

public MethodWrapper {
Method(void, Object) method;
public void setMethod(Method(void, Object) method) {
this.method = method;
}

public void doMethod(Object o) {
this.method(o);
}
}

public Main {
public static void main(String[] args) {
Main main = new Main();
MethodWrapper wrap = new MethodWrapper();

wrap.setMethod(main.hoge);
wrap.doMethod("特に意味なし");
}

public void hoge(Object o) {
System.out.println(o);
}
}


と言う風に使えます。

[ メッセージ編集済み 編集者: 英-Ran 編集日時 2003-07-19 16:06 ]
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2003-07-19 14:28
objectです。

>アットマーク・アイティ藤村@ITスタッフさん
基本的には、私は議論をするのであれば、立場その他もあると思いますが、議論の内容そのものが大切だと思います。
この様な発言は、万が一内容が事実であったとしても、この様な場所で発言すべき内容では無いと、私は思います。
私は、あの様な発言を受け、今後もその態度を変えないのであれば、この発言者と一切の議論をするつもりはありません。

最初、私はこの発言者の発言を無視する積もりでした。
でも、今回また私に対して問い掛けがありました。
私は前回の事がありましたから、応える積もりは全くありませんでした。
※実際、何を言うか分からない人と議論するのは、とても不安です!
しかし、何らかの形で、その理由を皆さんに伝える義務があると私は考えました。

今回、私が議論をしない理由を皆さんに分かって頂ければ、結構です。
スタッフの皆さんも、私が返事をしない理由を、どうかご理解ください。
ご迷惑をお掛けしました。
Izumi, Y.
ベテラン
会議室デビュー日: 2002/03/19
投稿数: 77
お住まい・勤務地: 東京
投稿日時: 2003-07-19 15:48
>object さん
引用:

例えば、(c)の「SampleEvent」をメソッドの引数にする時、どの様に書けば良いのでしょうか?


これは自己完結されていませんか。そう、
コード:
void DoSomething(Method(object sender, EvnetArgs e) sampleEvent) {}


と書くだけの話です。確かに書くのは面倒ですが、ちゃんと sampleEvent は引数になっていますよ。

さて、(c)と(d)の違いの件ですが、これではだめなのでしょうか。
コード:
  public methodtype void Method(object sender, EvnetArgs e);    (d')
  public event Method SampleEvent;
  c1.SampleEvent += c2.Sample_Handler;


delegate というキーワードではもとの意味と混同するとまずいので、methodtype という別のキーワードにしてみました。
さて本題ですが、object さんが言うところの「メソッドに型付けをする」という目的は一番上の methodtype 文で実現できています。しかし、イベントハンドラのリストに追加されているのはデリゲートではありませんね。メソッドへの直接参照です。私は、(d)と(d')の違いの中に、メソッドオブジェクト(a)とデリゲート(b)の本質的な違いが隠れていると考えています。

引用:

※「event」を型付けする事の重要性は、「Delphi」で既に認識されていると思います。


いや、イベントに型はいらないはずですよ。
これに関しては、今はちょっと頭の中の整理がつかないので、自分なりに整理できたらまた書きます(逃げになってしまって失礼)。
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2003-07-19 17:43
引用:

英-Ranさんの書き込み (2003-07-19 14:27) より:

これが本当ならば、配列型(例えばString[]型)の型チェックが行われないということになってしまいますね。メソッドオブジェクトを採用する場合、型チェックつけた状態で言語仕様に持ち込むのは当然です。

# という話がソースコードから読み取れなかったのなら申し訳ない



読み取れてませんでした(汗)。
解説までしてもらっちゃって申し訳ないです。
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2003-07-19 18:43
>>英-Ranさん
すいません、確かに「実装責任を渡す事」では若干広すぎますね(「処理」という言葉がぱっと思いつかなかったんです)。

で、今の議論ですが、議論を進めてきて「メソッドオブジェクト」の問題にうつっているようですので、それついて自分の考えを述べたいと思います。

英-Ranさんがおっしゃるようにメソッドのfirst Class Object(正確にはSourceを含めたもっと広域的なものだったと思います)についてはどこかで概念を見て「おもしろい概念だな」と思った記憶が実はありますので概念自体には私は否定の意見はないです。ただ、C#では実現されていない(というよりもC# delegateでにたような事はできるので十分と私は思いますが)。これについては、いくつか難しいな、と思う点があるので挙げてみたいと思います(「概念」を否定しているのではありません、「組み込むことが難しい」といっているのです)。

コード:

using System;
using System.Data;

public class Sample
{
private static void Main()
{
string[] sarr = new string[0];
Console.WriteLine( "String[] Assembly : " + sarr.GetType().Assembly.FullName );
DataSet[] dsetarr = new DataSet[0];
Console.WriteLine( "ArrayList[] Assembly : " + dsetarr.GetType().Assembly.FullName );
Console.Read();//出力見るためにまっているだけ
}
}




これはおもしろい結果を返します。私の環境では

String[] Assembly : mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
DataSet[] Assembly : System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

となります。そのアセンブリには配列型など定義されていないにもかかわらず、です。つまり、暗黙的にクラスを定義したときに配列型も同時に作っているようなものです。この実装に問題はあるか、答えはノーだと思います。
で、メソッド型が.NETにあったとして以下のコードではどのようになるでしょうか。

コード:

public class Sample
{
private static void Main()
{
Console.WriteLine( "void method() Type's Assembly : " + typeof(void method()).Assembly.FullName );
Console.Read();
}
}




上の方式ならばこの形を持ったメソッドがアセンブリリンク階層ではじめて定義された場所、になりますので、mscorlibあたりになるんでしょうか。
つまり、MyAssembly.dllとMyAssembly2.dllが同じこの形式のMethodでやり取りしようとした場合mscorlibを参照してmscorlibで使用されたクラスのメソッドと同時に暗黙的につくられたMethodの型にしたがってやりとりをする、と。私はこんな方式はいやです(この場合だとすべてのアセンブリのrootのmscorlibに入っている(だろう)から問題ないかもしれませんが、同じ階層に複数あったらどうします?)。
配列との根本的な違いはこの辺ではないでしょうか。

結局暗黙的なメソッドオブジェクトの型定義だとこのように、結構大変な事になってしまうんです。だから結局「明示的に型定義するほうが望ましい」ってことになります。また、参照のしやすさを考えると名前をもっていてくれるほうがありがたいです。
しかし、結局「すべてのメソッドに型を持たせるのはNG」になってしまったら型を持ったメソッドと型を持たないメソッドに分けることより、「メソッドに型などないしオブジェクトでない」の方が良いでしょう。


と、ここまで書いてきて思ったのですが。.NETのStrongly Type SafeはすべてのTypeを「世界にたった一つのType」と定義している点ではまずまずだと思います。これと、メソッドオブジェクトを統合するのは根本的に無理なんじゃないでしょうか。

[ メッセージ編集済み 編集者: ya 編集日時 2003-07-19 19:05 ]

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