2013年6月25日

VB.NET のダブルコーテーション(二重引用符)

VB.NET のダブルコーテーション(二重引用符)は、 全角「“”"」 半角「"」すべて半角として解釈される。
※Visual Studio のエディタは全角ダブルコーテーションを自動で半角にするため、下記を試す場合はテキストエディタ+vbcで

'文字列リテラルの開始と終了も全角使用可能(全角半角の混在も可能)
'文字列リテラル内の全角ダブルコーテーションはエスケープが必要
Dim strings = {”a”, “b“, "c", "””", "““", """"}
Console.WriteLine(String.Join(",", strings)) '結果「a,b,c,",","」

'文字リテラルも同様
Dim chars = {”a”c, “b“c, "c"c, "””"c, "““"c, """"c}
Console.WriteLine(New String(chars)) '結果「abc"""」

そのため、文字列リテラルでは、全角ダブルコーテーションが表現できない。
非.NET の VB から続く残念仕様・・・
全角ダブルコーテーションが必要な場合は、定数として定義しておくのがベター。

Public Class SpecialChars
    Public Const LeftDoubleQuote = ChrW(&H201C)  '“
    Public Const RightDoubleQuote = ChrW(&H201D) '”
    Public Const FullwidthQuote = ChrW(&HFF02)   '"
End Class

2013年6月19日

Dim と var

意味は異なるが、型推論の導入により、C#.NET と VB.NET で同じような構文で書けるようになった。
ただ、Dim の方が複数宣言できるので便利。元々、複数宣言可能だったのが、型推論でさらに便利になったというか。
対してvarは複数宣言不可。
理由は、「var val1=1, val2=1.0;」などの場合に型が1つに推測できないから?
複数の型が推測される場合は複数行に展開してくれたら便利だよね・・・

  • Dim (VB.NET)

'[Option Infer On]設定
Dim num = 1 'Integer型
Dim text = "1" 'String型

'複数宣言可能
Dim val1 = 1, val2 = 2, val3 = "1"
  • var (C#.NET)

var num = 1; //int型
var text = "1" //string型

//複数宣言 → コンパイル不可
var val1 = 1, val2 = 2;

Dim の変数宣言+New

Dim に型推論機能が追加されて、変数宣言+Newの省略記法が増えた。
どちらを使うかは好みの問題(生成されるMSILは同じ)だが、クラスのメンバ変数の場合は「As New」しか使えない。
※「As New」は、メンバ変数宣言でも使える省略記法であり、C# より便利な点。

Private Sub Test
    '今までの方法「As New」
    Dim hoge1 As New Hoge()
    '型推論「= New」 ※[Option Infer On]設定
    Dim hoge2 = New Hoge()
End Sub

'メンバ変数で使用可能 (実質、型が省略できる)
Private _hoge1 As New Hoge()

'コンパイル不可(メンバ変数は型推論不可)
Private _hoge2 = New Hoge()

2013年6月2日

キャストの比較 #2 オーバーフロー

キャストまたは算術演算(+、-、*、/) でオーバーフローが発生した際の挙動は、2種類ある。
  1. OverflowException をスロー
  2. 結果の最上位ビットを破棄

どちらの挙動にするかは、プロジェクト単位の設定、または C# なら checkedunchecked 構文が使える。
逆に言えば、VB.NET はプロジェクト単位でしか、オーバーフロー時の挙動を制御できない。
また、プロジェクト単位の設定オプションは下表になるが、注意すべきは C# と VB.NET で設定するチェックボックスの意味が逆という点。
デフォルト設定は両方チェック OFF、つまり、C# はオーバーフロー時の例外を発生させない、VB.NET は発生させる、と逆の挙動になっている。
オーバーフロー時の挙動設定オプション (Visual Studio 2010) デフォルト設定
C#.NET プロジェクトのプロパティ → [ビルド]タブ → [詳細設定]ボタン
→ [演算のオーバーフローおよびアンダーフローのチェック]チェックボックス
チェック OFF
VB.NET プロジェクトのプロパティ → [コンパイル]タブ → [詳細設定コンパイル オプション]ボタン
→ [演算のオーバーフローのチェックを解除]チェックボックス
チェック OFF

定数値のオーバーフロー

定数値のキャスト・算術演算でオーバーフローが発生する場合、コンパイルの挙動が C# と VB.NET で異なる。
オーバーフローチェック無し オーバーフローチェック有り
C#.NET チェック有無に関わらず、コンパイルエラー。
unchecked 構文を使うとコンパイルできる。
VB.NET キャストはコンパイル可能。
算術演算はコンパイルエラー。
キャスト・算術演算ともにコンパイルエラー。
  • C# の例

//定数値のキャストでオーバーフロー → 要 unchecked
int val1 = (int)2147483648L;
//定数値の算術演算でオーバーフロー → 要 unchecked
int val2 = 2147483647 + 1;
  • VB.NET の例

'定数値のキャストでオーバーフロー → オーバーフローチェック解除でコンパイル可
Dim val1 As Integer = CType(2147483648L, Integer);
'定数値の算術演算でオーバーフロー → 常にコンパイル不可
Dim val2 As Integer = 2147483647 + 1;

MSIL比較

オーバーフローチェック有無による MSIL の相違点は、「.ovf」の有無。
例:数値型から int にキャストする場合
オーバーフローチェック無し conv.i4
オーバーフローチェック有り conv.ovf.i4

検証環境

Windows 7 64bit/Visual Studio 2010 SP1/.NET 4.0