C# は最強か その2

昨日の日記で C# のことをいろいろ書いてますが、Java との比較等が全く出てきてないことを不思議に思ってる人もいるかもしれません。その部分について補足しておきますとオレが Java を全く知らないからです。以上。あと、間違いもたっぷり含まれている可能性がありますので、今更ですが鵜呑みにしないでください、と断りを入れておきます。「入門出来ます」とか書いてますが、実用に耐えられるアプリケーションを作る為には .NET のライブラリを使う必要があるので、その辺りの解説書はもちろん必要になりますし。オレは持ってませんけどね…。

今日いろいろ調べていたら C# ではクラス内部にクラスを定義出来ることを知りました。こんな感じです(青字の部分)。

namespace myApplication
{
public class myClass
{
public static int count;
public class innerClass
{
public void inc() {
count++;
}
}

public int Count
{
get { return count; }
set { count = value; }
}
}
}

クラス myClass のメンバ変数 count にクラス innerClass からアクセスする為には static にしないと駄目なようで。使い勝手半減です…。プロパティ等を使ってやりとりするのであれば内部に定義してる意義が無くなりますし。Delphi の内部関数の動作を期待してただけに残念。ちなみに、myClass の内部に定義されている innerClass は myClass の外でもインスタンス生成可能です。

myClass.innerClass instance = new myClass.innerClass();

結局 myClass がクラス定義+ namespace として作用してるだけみたいです。

上記ソースを見てもらうと分かりますが、かなり記述は簡略化されています。曖昧とまでは行きませんけどね。この辺りはなんでもかんでもきっちり書かないと駄目な Delphi とは考え方が全く違いますねー。int i; と int i(); の違いと同じと言われればその通りですが。

あと、インスタンスの開放が出来ないのはなんともかんとも。本当に出来ないのですか?出来ますよね?出来ると言ってくれー!いつ回収されるのか分からない GC に頼ってデストラクタに終了処理を書いたりするとヤバいんだろうなー。

namespace MyApplication
{
public class Delete
{
public static void delete(IDelete ins)
{
ins.delete();
}
}

public interface IDelete
{
void delete();
}

public class myClass1 : IDelete
{
public void delete()
{
// 終了処理
}
}
}


myClass1 instance = new myClass1();
try
{
// 例外上等!
}
catch
{
// 例外発生。しょんぼり。
}
finally
{
Delete.delete(instance);
}

まどろっこしいですか?ですよねー。これなら素直に using 使えって話ですな。まぁ動的に確保していったIDeleteを実装してるクラスのインスタンスをまとめて終了処理とかは出来る気はするので、使い道が無い訳でも無さそうですが。IDisposable で Dispose を実装してもやっぱり外部からは呼び出せません(多分)。

とかやってたら instance に null を入れるとどうなるか?という疑問が湧いて来たので早速やってみたのですが、何も起こりませんでした。残念!プログラマには何もさせないつもりなのでしょうか。うーん。

追記

やっぱりインスタンスを開放する手段は無いようです。しかし、プログラマがリソースの管理を行った方が良いケース(開いたファイルを閉じるとか)では IDisposable を実装して using を使う、というのが C# 的に正しいプログラミングスタイルのようですね。try - finally よりも手間は少ないのは事実なので、とりあえず納得したことにしておきます。参考:ガベージコレクション入門: Microsoft .NET Framework の自動メモリ管理 Part I