VB.NET → C# 移植メモ

C#への自動変換

方法1はソースレベルでの変換のため可読性は高い(コメントも保持される)が、ビルドエラーが多発する。On Error Goto文やLike演算子などC#がサポートしない文法を用いている箇所はエラーになる。VBでは許される明示的でない型変換などもエラーになるので修正が必要になる。フォームデザイナによるフォームのデザイン編集はいちおう維持されるが、かなり修正が必要 (後述)

方法2は逆コンパイルのため等価なソースにはなるが可読性は低い。当然ながらコメントは消える。ILからの逆コンパイルのため、変数名などは維持される。フォームデザイナでフォームのデザインを編集できなくなる。またリソースの参照情報も失われる。

いずれも一長一短であり、完璧な変換にはならない。

SharpDevelopでプロジェクトをコンバート

  • SharpDevelopオープンソースの.NETのIDE
  • VBからC#へのコンバート機能がある(あった)。
  • ただし最新版ではコンバート機能がなくなっているので、バージョン4.4を用いる。
  • バージョン4.4を下記からダウンロードしてインストールする。

  • 変換元のソリューションファイルとプロジェクトファイルのバージョン番号を改竄する。(古いソフトのため最新のVisualStudioで作成されたソリューション/プロジェクトを開くとエラーになる)

ソリューションファイル

VisualStudioVersion = 16.0.29409.12  ← 16を12に改竄する

プロジェクトファイル

<Project ToolsVersion="15.0" …  ← 15を4に改竄する
  • SharpDevelop 4.4 でソリューションを開き、[Project]→[Convert]→[From VB.NET to C#]
  • 同じソリューション内にC#のプロジェクトが生成される。
  • SharpDevelopを終了し、ソリューションと変換前後のプロジェクトの改竄を元に戻す。
  • VisualStuduoでソリューションを開き、ビルドしてみる。(たぶんエラーが多発する。)
  • あとは手動で修正する。

【参考記事】

コンバートの前に

VB.NETのコードに Option Explicit On を追加して、曖昧な型を使用している箇所をチェックしてあらかじめ修正して動作確認しておいたほうがコンバート後の修正が減ってラクかもしれない。

コードの修正

型変換
  • VBでは数値型⇔文字列型の暗黙の変換が許されるが、C#ではエラーになる。
  • long型⇔int型の暗黙の変換すらC#ではエラーになるので、明示的にキャストする。
  • 代入文だけでなく、比較演算子でも型の不一致はエラーになる。
動的型
  • VBのObject型は動的型のような呼び出しができるが、C#のobject型ではエラーになる。
    • 動的な呼び出しが必要ならobject型のかわりにdynamic型を用いる。
    • そうでないなら適切な型宣言をするか、var(型推論)で宣言する。
    • VBでは変数の宣言時に型を省略するとObject型になることにも注意。
    • Option Strict OnであればVBでもエラーになる。
ループ変数の型
  • VBではfor文やforeach文のループ変数の型を省略できるがC#では明示しなければならない。
Exit ForとExit Do, Continue ForとContinue Do
  • VBではループが入れ子のとき、 Exit ForとExit Doはそれぞれ独立。
  • C#ではループが入れ子のとき、breakはループの種類によらずいちばん内側のループから脱出。
  • VBのContinue For, Continue Do と、C#のcontinueについても同様。
On Error GoTo文
  • On Error GoTo文を用いたエラー処理は try / catch文による構造化例外処理に書き換える。
引数の省略
  • VBでは Hoge(a, ,b) のように省略可能な引数は途中の引数であっても省略できる。
  • C#では通常の引数(位置引数)は途中の引数を省略できない。
  • 途中の引数を省略したい場合は名前付き引数を用いる。 Hoge(A:a, B:b)
論理演算子と ビット演算子
Like演算子
配列の宣言
  • VBでは添字の最大値を指定して宣言する。
  • C#では要素の数を指定して new する。 (移植するには+1する)
ラベル
  • C#ではラベルの後に何も文がないとエラーになる。
  • ラベルのあと何もしない場合はセミコロンだけの空文を入れる。
エスケープシーケンス
  • VBの文字列リテラルにはエスケープシーケンスは無い。vbNewLineなどの定数を用いる。
My

フォームデザインの修正

フォームのソースは *.cs と *.Designer.cs に分けて変換されるが、変換に不具合があるのかフォームデザイナで開くと「データが失われる可能性を防ぐため、デザイナーの読み込み前に以下のエラーを解決する必要があります。 」と表示される。
*.Designer.cs をエディタで開いてみると、コントロールの宣言が奇妙なことになっているので修正する。以下に修正の例を示す。ただし修正をするとイベントハンドラの紐づけが失われるので、再設定する必要がある。
【修正前】

private System.Windows.Forms.Button withEventsField_btn_Cancel;
public System.Windows.Forms.Button btn_Cancel {
    get { return withEventsField_btn_Cancel; }
        set {
            if (withEventsField_btn_Cancel != null) {
                withEventsField_btn_Cancel.Click -= btn_Cancel_Click;
            }
        } …(中略)...
}

【修正後】

private System.Windows.Forms.Button btn_Cancel ;