2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SharpDevelop で、VB.Net を C# に変換してみた( その2 )

Last updated at Posted at 2021-04-15

背景

前回やったことの続きです。

ShartDevelop を使って、VB.Net のソースを C# に移行しようというプロジェクトの日記にしようと思います。

さて、前回でごく基本的な文法の変換は完了してエラー無く移行ができましたが、まだまだ難敵がいました。

  1. 拡張メソッド
  2. グローバル関数
  3. インデックス付プロパティ

まだまだ新たな敵が出てくるかもしれませんが、とりあえずこいつらをやっつけていきます。

拡張メソッド

前回のでスライムたちを倒して、レベルアップした気になってますが、拡張メソッドは手修正が必要なだけで、おそらく四天王の中でも最弱です。

基本的には、次のページを参照。

この注釈部分がちょっと分かりにくいですが、注釈にある一つ目の「拡張メソッド」のリンク先は、VB の拡張メソッド。二つ目の「拡張メソッド」は、C# の拡張メソッドの説明なのでそれぞれ確認。(さらに、this が、「この」に翻訳されているのがさらに難解にさせているという💦)

Before
<Extention>
Public Function Hoge( value As String ) As Integer
    Return HogeInternal( value )
End Function
After
public static int Hoge( this String value )
//                      ↑ ここに this を追加
{
    return HogeInternal( value );
}

基本的には、Extention 属性を削除して、関数の第一引数に this をつけてあげればよさそう。

また、他の VB で作成した dll にある Extentions 属性で作成した拡張メソッドは、そのまま C# で使えたのでそこは一安心。

グローバル関数

これは、まだはっきりしてませんが、c# にはグローバル関数(クラス名や名前空間を省略しての関数呼び出し)ができないのではないでしょうか?

つまり、VB だとこんな感じでした。

Before
Module Module1
    Public Function Hoge( value As String ) As Integer
        Return Fuga( value )
    End Function
End Module

Public Class Foo
    Public Sub Bar( value As String )
        Dim x = Hoge( value )
    End Sub
End Function

つまり、Module で宣言した関数はクラス名等を指定せず使用できました。
これが、C# だとできない気がして、下記のようになってます。

After
static class Module1 {
    public static int Hoge( String value )
    {
        return Fuga( value );
    }
}

class Foo {
    public void Bar( String value )
    {
        var x = Module1.Hoge( value );
        //      ↑ Module1 を明示的に指定
    }
}

これって、追加する作業も面倒ですが、VB に慣れてると今後のメンテナンスが面倒だなぁと思ってしまいました。
(追記)呼び出し側のソースの最初に、using static Project1.Module1みたいに書いてあげればいけました💦もうちょっと詳しくは、「VB.Net から移行した人のための C# Tips」に記載しました。

#インデックス付プロパティ

最後に、インデックス付プロパティ。
これが、VB から C# への変換のラスボスだと信じたい。

VB では、下記のようにプロパティにインデックスを使えます。

Public Property Hoge( index As Integer ) As String

これが、ググるとすぐに分かりますが C# には無い💦
インデクサというのが代わりに使えるっぽいので調べてみると、VB でいう Default Property がインデクサ相当ですね。

例えば、Dictionary クラスの Item なんかも、C# ではインデクサとして実装されていて、Item という名称のプロパティが無いという。

つまり、

Dim value = dic.Item( key )
Dim value = dic( key )
' ↑ どちらも OK

ですが、

var value = dic.Item( key )
// ↑ そんなプロパティは無い
var value = dic[ key ]
// ↑ インデックスとしてアクセスで OK

となります。

比較的、このリンクがその辺りを理解しやすい気がします。

びっくりしたのですが、.Net の SortedDictionary のソースを見たら、Item なんてプロパティはどこにもなくて 260 行目あたりにインデクサの宣言があるだけなんですね。

というわけで、Item のようなプロパティだけだったら、それを Default Property にしてあげれば OK。

引数が、Integer だったら全部の値を取得して、配列を返してあげるようにするのが候補の一つ。ただ代入もできるようにすると面倒。

代入もできるようにするには、delegate を引数に取る専用クラスを使うか、ref 変数を戻す関数に変換してあげればできそうな気がするけど、まだ検証中です。

メンテナンス性が微妙ですが、とりあえずは get_Item, set_Item とかに書き換えるのがよさそう。

Before
Dim x = y.Prop( z )
y.Prop( z ) = x

を移行するとこんな感じ。

After
var x = y.get_Prop( z )
y.set_Prop( z, x )

プロパティを関数呼び出しすればいいんでしょうけど、イマイチ感が否めないですね😖

まだ前途多難な感じです。

その3に続くかも !?

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?