- PR -

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

投稿者投稿内容
mizu
会議室デビュー日: 2003/07/22
投稿数: 2
投稿日時: 2003-07-23 02:15
引用:

yamasaさんの書き込み (2003-07-23 01:21) より:
yamasaです。

すぐに思いつくものとしては、

  • inner class の instance への参照がまだ生きているのに、enclosing instance が回収されてしまうことがある。
  • inner class の instance をシリアライズするとき、enclosing instance が一緒にシリアライズされなくなる。

といったところでしょうか。



前者は別に良さそうですが(回収される時点で、inner classのインスタンス以外は、
enclosing instanceを参照していないはずなので)、後者はまずそうですね。
英-Ran
ベテラン
会議室デビュー日: 2002/06/12
投稿数: 55
投稿日時: 2003-07-23 09:05
引用:

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

  • inner class の instance をシリアライズするとき、enclosing instance が一緒にシリアライズされなくなる。

といったところでしょうか。



VMから見ればinner classだってただのクラスだと考えると、inner classのインスタンスだけがデシリアライズされても問題ないような気もしますけれど。

私は何か問題を見落としてるのかな……
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2003-07-23 12:53
引用:

yamasaさんの書き込み (2003-07-22 15:43) より:
ところで、同様の問題は C# の Anonymous methods にもあると思うのですが、
こちらはどのように対処されているのでしょうか? > 識者の方

私は、k-nakさんと見解が少し違います。

マイクロソフトの資料によると、「Anonymous methods」は「Lisp」のラムダ式をイメージしているようです。
C#での書き方は、以下の様になるみたいです。
コード:
public class MyForm {
  ListBox listBox;
  TextBox textBox;
  Button button;
 
  public MyForm() {
    listBox = new ListBox(...);
    textBox = new TextBox(...);
    button = new Button(...);
    button.Click += new EventHandler(sender, e) {
      listBox.Items.Add(textBox.Text);
    };
  }
}

それで、お伺いの点ですが、
プログラム表記としては、上の様にデリゲートにハンドリング部分だけを追加コーディングする形です。
これに対して、コンパイラがクラス、メソッドに対して一意な名前を割り当て、ハンドリング部分の実装等、全ての面倒を見る様です。
従って、ハンドリング部分以外は、記述形式に隠蔽されていますから、コンパイラにバグが無ければ、ご指摘の問題は発生し無いと私は考えます。
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-23 15:56
引用:

IZUMI Yusukeさんの書き込み (2003-07-23 01:02) より:
改行文字がないにも関わらず「改行が入っている」と怒られていることから,ひょっとしたら文字コードを変更すれば何とかなるかもしれません。
#すでにいろいろな文字コードを試されていたらごめんなさい。



アドバイスありがとうございます。(結論を急ぎ過ぎましたね)
UTF-8形式にしたところ、日本語処理は可能であることを確認しました。

フォームの表示ですが、いただきましたご指示をもとに
csc /r:System.Windows.Forms.dll ~/form.cs または
csc /r:System.dll /r:System.Windows.Forms.dll ~/form.cs
で試してみました。いずれも
error CS0006:
Metadata file 'System.Windows.Forms.dll' could not be found
となってしまいました。(Forms クラスが存在していないか見つからない?)
何か違っている可能性もありますので、もしLinux等での実装ノウハウでも
よろしいですので、ご教示いただけたら有り難いです。
よろしくお願いいたします。

# 追記
# ようやく尾島氏のJava VS .NET が掲載されている.NET マガジン8月号を買いました。
# 両者の違いがマクロ的な視点で解説されていました。

[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-07-23 20:12 ]
yamasa
ベテラン
会議室デビュー日: 2003/02/15
投稿数: 80
投稿日時: 2003-07-24 02:53
引用:

mizuさんの書き込み (2003-07-23 02:15) より:
引用:

  • inner class の instance への参照がまだ生きているのに、enclosing instance が回収されてしまうことがある。
  • inner class の instance をシリアライズするとき、enclosing instance が一緒にシリアライズされなくなる。


前者は別に良さそうですが(回収される時点で、inner classのインスタンス以外は、
enclosing instanceを参照していないはずなので)、後者はまずそうですね。


いえ、前者の場合でも、enclosing instance(もしくはそれと同時に
ガベージコレクトされるインスタンス)が副作用のある finalize メソッドを
定義している場合は挙動が変わってしまいますよね。
他には、WeakReference などの挙動も変わるでしょう。

引用:

英-Ranさんの書き込み (2003-07-23 09:05) より:
VMから見ればinner classだってただのクラスだと考えると、inner classの
インスタンスだけがデシリアライズされても問題ないような気もしますけれど。


いや、それ以前の問題で、最適化を行なうVMと行なわないVMそれぞれで
シリアライズした結果のバイト列が異なってしまいますよね。

> objectさん
ええと、舌足らずだったかもしれませんが、
ここで言う「同様の問題」とは
引用:

一方、Java の anonymous class および local class の場合、
enclosing instance への参照を持つかどうかは
それらが定義されているコンテキストが static か否かで決まります。
よって、たとえば enclosing instance への参照を持たない anonymous class を
非staticメソッドの中で宣言することは不可能ということになります。


の部分に対応するものです。
つまり、Anonymous methods により生成された delegate インスタンスに
委譲先インスタンスへの参照を持たせるか否かを、どうやって決めているのか
知りたいわけです。
Izumi, Y.
ベテラン
会議室デビュー日: 2002/03/19
投稿数: 77
お住まい・勤務地: 東京
投稿日時: 2003-07-24 03:29
引用:

フォームの表示ですが、いただきましたご指示をもとに
csc /r:System.Windows.Forms.dll ~/form.cs または
csc /r:System.dll /r:System.Windows.Forms.dll ~/form.cs
で試してみました。


う〜ん、やはり Windows フォームは鬼門かもしれませんね。
ひょっとして拡張子が .DLL でなかったりして。csc /r:System.dll foo.cs (foo.cs はコンソール・アプリケーション)はどうなるでしょう。

私も個人で Linux は少し使っていますので(基本的にはサーバー用途ですが)、Mono Project あたりは機会があれば試してみたいところではありますね。
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-24 06:57
引用:

IZUMI Yusukeさんの書き込み (2003-07-24 03:29) より:
う〜ん、やはり Windows フォームは鬼門かもしれませんね。
ひょっとして拡張子が .DLL でなかったりして。csc /r:System.dll foo.cs (foo.cs はコンソール・アプリケーション)はどうなるでしょう。


一応、dll ファイルは存在しているので恐らく拡張子はdllかな、とみていますが
確証はないです。(というよりC#のファイル構成自体殆ど分かっていないので)
/r:system.dll だけですと
The type or namespace name 'Windows' does not exist ・・・
となってしまいます。

【追記】
コンソールプログラムにおいては/r:System.dll を追加してもコンパイルします。

いずれにせよ、Shared source CLIの検証は時間がかかってしまう作業なので
一旦Thread.sleep()しておきたいと考えます。大きなeventが発生したら再開
ということで。有難うございました。

【蛇足】
同一マシン(Pentium III 1GHz Memory 256MB Windows2000SP3)で、和差積商の
2億回ループにかかる時間を計測しました。(何故2億回なのかですが、
マニュアル計測しやすい時間に終了するからです。)
それぞれコンパイル後3回実行した後、5回計測した時間の平均値を求めました。
C#(.NET Framework1.1) 7.56秒 / Java(jdk1.4.1_03) 7.67秒
ということで、C#が1.5%程上回っております。無論この差は差ではないことは
明白です。
# Mac OS X におけるShared source CLIは、clixの起動に若干時間がかかります。

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

yamasaさんの書き込み (2003-07-24 02:53) より:
いえ、前者の場合でも、enclosing instance(もしくはそれと同時に
ガベージコレクトされるインスタンス)が副作用のある finalize メソッドを
定義している場合は挙動が変わってしまいますよね。
他には、WeakReference などの挙動も変わるでしょう。



具体的には、どのようなfinalizeメソッドが問題となるのでしょうか。finalizeがいつ呼び出されるかはわからないので、そんなfinalizeを作ることの方に問題があるような気がするのですが。WeakReferenceも同様ですが、そもそもJavaで同じ挙動が起こると期待されない場面のような気もします。

引用:

いや、それ以前の問題で、最適化を行なうVMと行なわないVMそれぞれで
シリアライズした結果のバイト列が異なってしまいますよね。



バイト列が異なることによってどのような問題が起こるのでしょうか。コンパイル時点で同一のバイトコードが生成されることはJava言語仕様で規定されていない(例えば、未使用の変数を削除するかどうか、private変数の変数名を変換するか否か)ので、これも特に問題ではないような気がします。

# 言語仕様でできないと書いてあるからできないんだというのは了解してますが
# 問題点を理解しておきたいので。
# しつこく感じたら、申し訳ない

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