月別アーカイブ: 2010年12月

3 posts

VB to C# 3

VBプロジェクトからC#プロジェクトへの書き換えは、
次のように三つのプロジェクトを開いて作業しています。
一つ目はオリジナルのVB2010プロジェクト(以下[VBPro]といいます)、
二つ目はSharpDevelopで変換したC#プロジェクト(以下[SDevPro]といいます)、
三つ目は新規のC#プロジェクト(以下[新規Pro]といいます)です。

最初は二つ目のプロジェクト[SDevPro]ですべて作業していたのですが、
SharpDevelopの変換は不十分で、
それに沢山の修正を加えてゴチャゴチャにするよりも、
新たにプロジェクトを構築していく方がすっきりしてよいと気づき、
新規のプロジェクトを一から構築することにしました。

まず、Formを継承していないクラスファイルは問題が少ないので、
ほぼそっくり[SDevPro]から[新規Pro]にコピーします。

VBはすべてがいい加減で(言葉は適切ではありません)、
C#はすべてが厳密だという問題が出てきます。

すぐ問題になるのが名前空間[namespace]です。
プロジェクトが大きくなるとサブフォルダを作ることは至極当然です。
VBでは、特に[namespace]を気にしなければ、
フォルダに関係なく一つの名前空間の下に管理されます。
C#ではフォルダをつくり、その中にクラスなりフォームなりを作成すると、
そのクラスの[namespace]は、
[ルート名前空間 + ドット + フォルダ名]になります(Javaと同じです)。

プロジェクトのなかでも別のフォルダを使うときには、
[using]で必要なサブフォルダ=[namespace]を呼び込んでおかなければなりません。

後でフォルダ名を変えたり、ファイルの移動をしたりするとどうなるか。
ソリューション エクスプローラでファイルを[切取]、[貼り付け]でフォルダを移動しても、
[Visual SourceSafe 2005]は問題ありませんが、
当該クラスで記述した[namespace]は自動では変更してくれませんので、
手動で変更しなければいけません。

100%ではありませんが、
この辺りはVS2010の[リファクター]やDecXpressの[RefactorPro!]が十分働いてくれます。

フォームを継承したクラス(要するにForm)のデザイン画面は、
[VBPro]の画面をコピーし貼り付けても問題ないようです。
コードは[SharpDevelop]で変換した[SDevPro]のコードをコピーします。

どちらにしても自動変換の後はたくさんのエラーが表示されます。

VBメソッドの[Optioal]はC#でサポートしていない」ので、
一部書き換えを始めていましたが、C#2010からC#でもこれをサポート。
C#ではもっと簡単に、
引数定義の後ろに[=]に続いてデフォルト値を書くだけでいいと分かり(たとえば[= true])、
「よかった!!」という感じです。
実はこの変更もどのように統一的な形にするか悩んでいました。

C#への書き換えで気づいたのは、
VBのプログラミングムでは私自身「ずいぶんいい加減に書いてきたな」ということです。

その一つが、[ByRef]の使い方です。
メソッド側で変更がある場合は、碌に考えもしないで[ByRef]を使っていました。
VBでは害にもならないのですが、
C#ではコールする側にも[ByRef]に相当する[ref]を書かなければいけません。
しかもコールする側でこの変数に値を代入しておかなければエラーになります(VBでは警告)。

反対にメソッドを呼ぶ側でなく、呼ばれるメソッド側で値を作る場合は、
呼ぶ側も呼ばれる側も[out]キーワードを付けなければいけませんし、
呼ぶ側は変数定義だけでにしておかなければいけません。
呼ぶ側で変数に値を設定するとエラーになります。

もう一つ面倒なのは、C#で参照渡し([ref]あるいは[out])でメソッドを呼ぶとき、
オブジェクトの[プロパティ]を引数に渡すことはできません。
例えば、商品台帳(クラス)の価格プロパティをメソッドで変更しようとして、
価格プロパティだけをメソッドに渡すことができません。
プログラムを改変する必要があります。
この辺りは「C#は融通が利かない」とみるか、「厳密でいい」とみるか意見の分かれるところです。

現在DBでは[Ado.Net]、[Linq to SQL]、[Linq to EF]を節操もなく使っていますので全面見直しです。
まだ先は長そうです。

どちらにしても、
[VB to C#]の変換作業はVBプログラマにとって最も効率のいいC#の勉強法だと思います。

C# 参考書

昔-Windows以前の世界では-FortranやCを使っていて、
オモチャっぽいBasicは好きではありませんでした。

WindowsでVBが発売されたとき、
統合開発環境=IDEの充実した言語としては他にVC++しかありません。
VC++のフレームワークはあまりにゴチャゴチャしていて、
予想どおり大多数の人はVC++を使って来ませんでした。

私もVC++はあまり使わず、結局長い間VBを使ってきました。
VBの教科書としてはBalenaの翻訳本がとてもいいと思います。
BalenaがVB.NETに書き換えたとき躊躇せず購入しましたし、
VB2005の解説書も購入しました。
私は完全にBalenaを信頼しています。

今回本格的にC#の勉強をしようと参考書を物色しましたが、
日本語の「いい教科書がない」と痛感しました。
書店には「・・・入門」はたくさんありますが、中級以上の本がない。

私はよく思います。
「なぜ日本語のいい教科書がないのだろう」と。
理由は色々あると思いますが、一つは投資対効果でしょう。
一冊の本をしっかり書くことは大変な労力を必要としますが、
数年でバージョンが変わるソフトを追いかけて、
大して売れもしないうちに次々教科書を出版するのは採算に合わないのでしょう。

英語圏であればそれなりの購買層があるが、
日本語に特化すると商売にならないのでしょう。
結局私たちは中級以上の本は賞味期限を過ぎた翻訳本か、
それが嫌なら原書を読むしかありません。

ついでですが、「調べる」にはオンラインヘルプはいいが、
「勉強」には本の方が数段勝ると思います。

今回C#のプログラムを書くにあたって、いい教科書に出会えません。
[プログラミング VIsual C# 2005]はもはや話題が古くLINQ等の記述がありません。
[Pro C# 2010 and the .NET 4 Platfrom](Apress)は1600ページ以上あって、
英語ですから拾読みするには適当ではありません。通読する時間などありません。
[C# 4.0 In a nutshell](O’Reilly)がリファレンスとしては一番いいかもしれません。

出版社に提案があります(出版社がこのブログを読んでいるとは思いません。独り言です)。
日本語の[・・・入門]はやめて、英語の定評のある参考書の翻訳本を素早く出版していただきたい。
これは出版社に対してのお願いというよりマイクロソフトへのお願いです。
マイクロソフトは[Microsoft Press]だけでなく、
他社の書籍に対してもいい翻訳本を迅速に出す工夫をしていただきたいと思います。

いい教科書があるかどうかは、その言語が広く使われるかどうに大きく影響します。

このような状態では、英語に弱い日本のソフト技術者は、最前線からどんどん追いやられてしまいます。

インドや中国の技術者の進出を見れば、彼らの勢いを肌で感じるでしょう。
ソフトにかかわる人は、「彼らを使えば安く開発できる」とのんきなことをいっている場合ではないでしょう。
ソフトウェア技術者も英語の技術書を「読む」くらいは身につけなければいけません。

大学の教養科目の英語で「文学書」の一節を勉強するなど間違っています(私の学生時代)。
大学生になればそれぞれに教養として専門書が読めるようにすべきです。
専門書はそもそも文学書と違って「凝った」表現はないのです。
自分の専門分野に限れば単語も数多くあるわけではありません。
ある種「慣れ」で、母国語程度とはいきませんが、慣れればいくらでも読めるのです。

今の大学の教養授業は変わったのでしょうか。

VB to C# 2

VB.NETからC#.NETへの変換では、
SharpDevelopは大いに助かるのですが、
結局ややこしいところは自動処理してくれなくて手作業で書き直さなければいけません。

全面書き換えには次のようなものがあります。

画面
LINQ
インデクサ

そのほかVBでよく使うメソッドでC#ではどうかけばいいのか分からないケースがあります。
たとえば、二つの日付の差の日数を計算する[DateDiff]や変数に数字が入っているかを調べる[isNumeric] 等をC#ではどう書けばいいか結構調べまわることになります。

LINQでは明示的に型指定のない変数(VBではDim、C#ではvarで宣言)をよく使います。
VBではつぎのように条件文の外で変数を宣言し、条件によるLINQ文の結果をその後で使っていくことができます。

Dim query
If true then
    query= From rec In 商品tbl Where rec.CD = “1234”
Else
    query= From rec In 商品tbl Where rec.CD = “5678”
End If

それどころが明示的に型指定のない変数をクラス変数(フィールド)にさえ使えます。

一方C#では、型指定のない変数は厳密にローカルにしか使えませんし。
上のコードのように初期化なしの宣言だけも許されません(nullでの初期化も不可)。

C#では型指定するか、プログラムの構造を変えるしかありません。

また、[LINQ toSQL]と[LINQ to Entiry Framework](以下LINQ to EFと書きます)との使い分けがまだよく分かりません。
おそらく、[LINQ to EF]に統一すべきだと思いますが、我がプログラムはまた統一していません。
[LINQ to SQL]は身軽な感じがしているので、
簡単なSQLはこちらが便利かなと思っています。

VBではLINQやデリゲートやジェネリックを使ってきましたが、
VBの緩い約束事にしたがって、「いい加減に使ってきたかな」という感想を持っています。

この際、「デリゲート、ジェネリック、LINQ、ラムダ式をキッチリ理解しなければいけない」
と考えています。
正味1、2ヶ月は必要かもしれません。