• 追加された行はこの色です。
  • 削除された行はこの色です。
#title(.NETプログラミング研究 第11号)

#navi(.NET プログラミング研究)
#navi(.NETプログラミング研究)

#contents

*.NETプログラミング研究 第11号 [#k1527adb]

**ピンポイントリンク [#q5a61c2d]

***C#のコードをVB.NETへ変換する(及びその逆) [#s37ef209]

#column(注意){{
この記事の最新版は「[[C#のコードをVB.NETへ変換する、VB.NETのコードをC#へ変換する>http://dobon.net/vb/dotnet/links/convertcs2vb.html]]」で公開しています。
}}

C#からVB.NETへのコード変換(及びその逆)のために役立ちそうなツールを探してみました。まずはC#からVB.NETへの変換から。

多分一番有名なツールは「Convert C# to VB .NET」でしょう。

-[[Convert C# to VB .NET>http://www.kamalpatel.net/ConvertCSharp2VB.aspx]]

このページのテキストボックスにC#のコードを入力し、ボタンをクリックすると、VB.NETのコードに変換されます。簡単なコードであれば大体うまく行くようですが、usingステートメントなどのように、うまく変換されないケースも多いです。

さらに残念なことに、日本語を含むコードを変換しようとすると、エラーになることがあります。

同ページから「Convert C# TO VB .NET OFFLINE」という実行ファイル形式のツールや、WebServiceを使用する時のサンプルもあります。

「Convert C# TO VB .NET OFFLINE」はソースが付いているため、改造も出来ます。日本語を正しく表示できるようにするためには、多少の修正が必要になります。
(Form1のtxtCSharpとtxtVBのFontを日本語フォントに変更し、FileToStrメソッド内の
StreamReader oReader = System.IO.File.OpenText(cFileName);
を
StreamReader oReader = new StreamReader(cFileName, System.Text.Encoding.GetEncoding(932));
と変更すれば、大丈夫そうです。)

またこれとは別に「C# to VB.NET Translator」というのがあります。

-[[C# to VB.NET Translator>http://www.aspalliance.com/aldotnet/examples/translate.aspx]]

先に紹介した「Convert C# to VB .NET」とは別のエンジンであり、さらに「Convert C# to VB .NET」よりこちらのほうが勝っているというようなことが書かれています。実際にそうであるかは分かりませんが、「Convert C# to VB .NET」でエラーが出る日本語を含むコードも、こちらではエラーが出ずに成功します。

逆に、VB.NETからC#へコードを変換するツールは今のところ私の知る限り「Convert Visual Basic .NET to C#」しかありません。

-[[Convert Visual Basic .NET to C#>http://www.ellkay.com/ConvertVB2CSharp.htm]]

しかし残念なことに、現在はC#へ変換されたコードは画像データとして表示されるため、コピーして使うことが出来ません。また、「Convert C# to VB .NET」と同様に、日本語を含むコードの変換でエラーが出ることがあります。

最後にVB.NETからC#へコードを変換する奥の手を紹介しましょう。それは、MSILのDisassembler(逆アセンブラ)を使う方法です。

Disassemblerは.NET Framework SDKにも「MSIL Disassembler」(Ildasm.exe)というのが付いておりそこそこ使えますが、C#のコードを得ることが目的であれば、「Anakrino」がお勧めです。

-[[Anakrino Download>http://www.saurik.com/net/exemplar/]]

使い方としては、VB.NETで書いたコードをビルドし、できたファイル(exeやdll)をAnakrinoで開くだけです。同梱されているExemplar.exeを使うと、いっぺんにC#のコードへ変換されますので、さらに便利です。ただし残念なことに、日本語が表示されません(Exemplar.exeは途中で終わってしまう)。

この方法であれば、VB.NETからだけでなく、他の言語からでもC#へコードの変更が出来るといえなくもないでしょう。

***.NETの命名規則2 - "m_"復活(?!)の巻 [#z2398713]

「.NETプログラミング研究 第3号」で「.NETの命名規則」について説明しました。その中でヘルプ内の不可解な説明に関していろいろ書かせていただきました。Visual Studio .NETもバージョンアップしたということで、ヘルプも修正されたかと思い調べてみたところ、ちょっと面白いことになっていたのでここで紹介します。

私が「.NETプログラミング研究 第3号」で具体的に指摘したヘルプにおける不可解な点は3箇所ありました。

まず、ヘルプの「静的フィールドの名前付けのガイドライン」で「静的フィールド名には、ハンガリー表記法を使用したプリフィックスを付けます。」と書かれている点について、間違いではないかと指摘しました。新しいヘルプを見てみるとどうやらそうであったらしく、「静的フィールド名には、ハンガリー表記法を使用したプリフィックスは付けません。」と全く逆に修正されています。

以前紹介した
「[[VB.NET コーディング標準>http://objectclub.esm.co.jp/eXtremeProgramming/CodingStdVB.pdf]]」
「[[C#コーディング標準>http://www.kawabata.com/dotnet/CodingStdCS.pdf]]」
では、しつこい位に「ハンガリアン表記法を使用しない」と書かれているのですが、なぜか共有変数の名前のつけ方に関してはそう書かれていません。どうもこのヘルプの間違いに惑わされたのではないかと思われますが、このようなヘルプの間違いは間接的にも影響が大きく、本当に困りものです。

-[[静的フィールドの名前付けのガイドライン>http://www.microsoft.com/japan/msdn/library/ja/cpgenref/html/cpconstaticfieldnamingguidelines.asp]]

2つ目の疑問点は、「フィールドの使用方法のガイドライン」において次のような実行不可能なコードが例として載っていることでした。(フィールド名handleとプロパティ名Handleが同じため、VBでは不可となります。)

#pre{{
[Visual Basic]
Public Class Control
      Inherits Component
      Private handle As Integer
      
      Protected ReadOnly Property Handle() As Integer
         Get
            Return handle
         End Get
      End Property
   End Class 
}}

このコードについては、残念ながら新しいヘルプでも修正されていませんでした。

-[[フィールドの使用方法のガイドライン>http://www.microsoft.com/japan/msdn/library/ja/cpgenref/html/cpconfieldusageguidelines.asp]]

最後に指摘した不可解な点は、「プロパティの使用方法のガイドライン」に上と同じく次のような実行不可能なコードが例として載っていることでした。

#pre{{
[Visual Basic]
Public Class TextBox
   Private dataSource As String
   Private dataField As String
   Private active As Boolean

   Public Property DataSource() As String
      Get
         Return dataSource
      End Get
      Set
         '(省略)
      End Set
   End Property
   Public Property DataField() As String
      Get
         Return dataField
      End Get
      Set
         '(省略)
      End Set
   End Property
   '(省略)
End Class
}}

これは新しいヘルプで修正されていたのですが、面白いことに次のように"m_"プリフィックスを付けるという、旧VBでは推奨されながら、.NETでは否定された、古き良き(?)方法が復活していました。

#pre{{
Public Class TextBox
   Private m_dataSource As String
   Private m_dataField As String
   Private m_active As Boolean

   Public Property DataSource() As String
      Get
         Return m_dataSource
      End Get
      Set
         '(省略)
         End If
      End Set
   End Property
   Public Property DataField() As String
      Get
         Return m_dataField
      End Get
      Set
         '(省略)
         End If
      End Set
   End Property
   '(省略)
End Class
}}

しかしこれが正しい方法として認定されたとも判断出来ないようです。

まず、「フィールドの使用方法のガイドライン」では、「フィールド名または静的フィールド名にプリフィックスは適用しません。」と明記されており、これに反しています。

さらに、C#のサンプルコードでは今まで通り、フィールド名とプロパティ名を先頭の文字が小文字と大文字かで区別していることを考えると、.NETの命名法に統一感がないことが分かります。

このような点からして、以前私の指摘した「プライベートなフィールドにアクセスするためのプロパティにはどのような名前をつけるべきなのか?」という問題はいまだに解決していないというのが実際のところのようで、これからもプログラマーを悩ませ続けることでしょう。

-[[プロパティの使用方法のガイドライン>http://www.microsoft.com/japan/msdn/library/ja/cpgenref/html/cpconpropertyusageguidelines.asp]]

**ピンポイントリンク [#dc0e2042]

***DataGrid内の特定のセルの色を変える [#yee581b0]

#column(注意){{
この記事の最新版は「[[DataGrid内の特定のセルの色を変える>http://dobon.net/vb/dotnet/datagrid/coloredcell.html]]」で公開しています。
}}

前回まではDataGridコントロール(System.Windows.Forms)での列スタイルの使い方について説明しましたが、今回はさらに発展させ、DataGridColumnStyleの派生クラスを使うことにより、より複雑な処理を行う方法を紹介します。

DataGrid内の特定のセルの色を変えるには、DataGridColumnStyle.PaintメソッドをオーバーライドしたDataGridColumnStyleの派生クラスを作成し、これを使うようにします。

まずは次のような派生クラスを作成し、Paintメソッド内でどのようなセルにどのような色をつけるか指定します。この例ではDataGridTextBoxColumnから派生したMyDataGridTextBoxColumnクラスを作成し、値が"0"のセルを前景色が白、背景色が黒で表示するようにしています。

#code(vbnet){{
'DataGridTextBoxColumnを継承してクラスを作成
Public Class MyDataGridTextBoxColumn
    Inherits DataGridTextBoxColumn
    'Paintメソッドをオーバーライドする
    Protected Overloads Overrides Sub Paint( _
            ByVal g As Graphics, _
            ByVal bounds As Rectangle, _
            ByVal source As CurrencyManager, _
            ByVal rowNum As Integer, _
            ByVal backBrush As Brush, _
            ByVal foreBrush As Brush, _
            ByVal alignToRight As Boolean _
            )
        'セルの値を取得する
        Dim cellValue As Object = _
            Me.GetColumnValueAtRow(source, rowNum)
        If Not cellValue Is Nothing Then
            '値が"0"のセルの前景色と背景色を変える
            If CType(cellValue, String) = "0" Then
                foreBrush = New SolidBrush(Color.White)
                backBrush = New SolidBrush(Color.Black)
            End If
        End If
        '基本クラスのPaintメソッドを呼び出す
        MyBase.Paint(g, bounds, source, rowNum, _
            backBrush, foreBrush, alignToRight)
    End Sub
End Class
}}

#code(csharp){{
//DataGridTextBoxColumnを継承してクラスを作成
public class MyDataGridTextBoxColumn : DataGridTextBoxColumn
{
    //Paintメソッドをオーバーライドする
    protected override void Paint(Graphics g,
        Rectangle bounds,
        CurrencyManager source,
        int rowNum, Brush backBrush,
        Brush foreBrush,
        bool alignToRight)
    {
        //セルの値を取得する
        object cellValue =
            this.GetColumnValueAtRow(source, rowNum);
        if (cellValue != null)
        {
            //値が"0"のセルの前景色と背景色を変える
            if ((string) cellValue == "0")
            {
                foreBrush = new SolidBrush(Color.White);
                backBrush = new SolidBrush(Color.Black);
            }
        }
        //基本クラスのPaintメソッドを呼び出す
        base.Paint(g, bounds, source, rowNum,
            backBrush, foreBrush, alignToRight);
    }
}
}}

次にセルの色を変えたい列にこの列スタイルを使うようにします。(列スタイルの説明は省かれています。)この例では、データソースが"Column1"という名前のDataColumnがある"DataTable1"という名前のDataTableであることを前提にしています。

#code(vbnet){{
'新しいDataGridTableStyleの作成
Dim ts As New DataGridTableStyle()
'マップ名を指定する
ts.MappingName = "DataTable1"

'列スタイルにMyDataGridTextBoxColumnを使う
Dim cs As MyDataGridTextBoxColumn
cs = New MyDataGridTextBoxColumn()
'マップ名を指定する
cs.MappingName = "Column1"
'DataGridTableStyleに追加する
ts.GridColumnStyles.Add(cs)

'テーブルスタイルをDataGridに追加する
DataGrid1.TableStyles.Add(ts)
}}

#code(csharp){{
//新しいDataGridTableStyleの作成
DataGridTableStyle ts = new DataGridTableStyle();
//マップ名を指定する
ts.MappingName = "DataTable1";

//列スタイルにMyDataGridTextBoxColumnを使う
MyDataGridTextBoxColumn cs;
cs = new MyDataGridTextBoxColumn();
//マップ名を指定する
cs.MappingName = "Column3";
//DataGridTableStyleに追加する
ts.GridColumnStyles.Add(cs);

//テーブルスタイルをDataGridに追加する
DataGrid1.TableStyles.Add(ts);
}}

**コメント [#sf83e629]
#comment

//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2003-06-30 (月) 06:00:00,DOBON!,2010-03-21 (日) 00:25:08,DOBON!)

[ トップ ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]