DOBON.NET
■プログラミング
.NET Tips
フォーム
コントロール
DataGrid
ファイル・フォルダ
画像・印刷
インターネット
システム
その他
インストーラ研究
■検索



Google

Web dobon.net
■掲示板最新情報
■.NET Ring
.NET Ring .NET Ringのホームへ移動 .NET Ringの前のサイトへ移動 .NET Ring参加サイト一覧 .NET Ringの次のサイトへ移動
.NET Ringに参加する 
■メールマガジン
.NETプログラミング研究」 詳細はこちら。
メールアドレス:
■その他
ソフトウェア
掲示板
メール
携帯専用サイト
リンク集
リンクをご希望の方へ
Translate this site into English...
■広告
■VS.NETを買うなら...
VS.NET Professional 2003 ステップアップグレード(\39,000)とVB.NET Standard 2003(\18,200)を買った方が、VS.NET 2003 Professional(\125,000)やVS.NET 2003 Professional MSDN DX(\155,000)より全然安い!!

学生ならVisual Studio .NET theSpoke Premium Version 2003がなんと、4千円以下で買える!!絶対お勧め!!

無料で.NETプログラミングを試してみたい方は、こちら

*上記の情報は05/10/2現在のもので、変更されている可能性があります。
DOBON.NET > プログラミング道 > どぼん!の.NET Tips > VB.NETユーザーのためのC#Tips

VB.NETユーザーのためのC#Tips- 全記事表示


VB.NETユーザーのためのC#Tipsメニュー


C#でIsNumeric、IsDateに代わるものは?

VBのIsNumeric関数は、指定されたデータが正しく倍精度浮動小数点数型(Double)に変換できる文字列であるか調べることができる関数です。Char構造体にはIsNumberやIsDigitというメソッドがありますが、これらは指定された文字が数字であるか調べるものであり、文字列には使えません。

C#でIsNumericの代わりになりそうな方法には、

  1. Double.TryParseメソッドを使う。
  2. Double.Parseメソッドで変換してみて例外が発生するか調べる。
  3. 正規表現で調べてみる。
  4. 一つ一つの文字を調べていき、適切かどうか確かめる。

などが考えられそうです。ここでは1と2の方法を紹介します。

1の方法は例えば次のようになります。ここではNumberStyles.AnyとNumberFormatInfo.InvariantInfoを指定していますが、必要に応じて変更してください(詳しくはヘルプをご覧ください)。

[VB.NET]
Dim str As String = "-12.34"
Dim d As Double

'doubleに変換できるか確かめる
If Double.TryParse(str, _
    System.Globalization.NumberStyles.Any, _
    System.Globalization.NumberFormatInfo.InvariantInfo, _
    d) Then
    Console.WriteLine("{0}は数字です。", str)
Else
    Console.WriteLine("{0}は数字ではありません。", str)
End If
[C#]
string str = "-12.34";
double d;

//doubleに変換できるか確かめる
if (double.TryParse(str,
    System.Globalization.NumberStyles.Any,
    System.Globalization.NumberFormatInfo.InvariantInfo,
    out d))
    Console.WriteLine("{0}は数字です。", str);
else
    Console.WriteLine("{0}は数字ではありません。", str);

次に2番目の方法です。これは例えば次のようになります。

[VB.NET]
Dim str As String = "-12.34"
Dim isnum As Boolean = True

'doubleに変換できるか確かめる
Try
    Double.Parse(str)
Catch
    isnum = False
End Try

'結果を表示
If isnum Then
    Console.WriteLine("{0}は数字です。", str)
Else
    Console.WriteLine("{0}は数字ではありません。", str)
End If
[C#]
string str = "-12.34";
bool isnum = true;

//doubleに変換できるか確かめる
try
{
    double.Parse(str);
}
catch
{
    isnum = false;
}

//結果を表示
if (isnum)
    Console.WriteLine("{0}は数字です。", str);
else
    Console.WriteLine("{0}は数字ではありません。", str);

次にIsDate関数です。VBのIsDate関数は、指定した文字列が日付型(Date)に変換可能か調べることができる関数です。IsDate関数の場合も先に示したIsNumeric関数の2〜4の方法が使えます。

次に2番目の方法を使った例を示します。

[VB.NET]
Dim str As String = "2000/1/1"
Dim isnum As Boolean = True

'DateTimeに変換できるか確かめる
Try
    DateTime.Parse(str)
Catch
    isnum = False
End Try

'結果を表示
If isnum Then
    Console.WriteLine("{0}はDateTimeに変換できます。", str)
Else
    Console.WriteLine("{0}はDateTimeに変換できません。", str)
End If
[C#]
string str = "2000/1/1";
bool isnum = true;

//DateTimeに変換できるか確かめる
try
{
    DateTime.Parse(str);
}
catch
{
    isnum = false;
}

//結果を表示
if (isnum)
    Console.WriteLine("{0}はDateTimeに変換できます。", str);
else
    Console.WriteLine("{0}はDateTimeに変換できません。", str);

C#でTypeOf...Is...に代わるものは?

C#でVB.NETのTypeOf...Is式に代わるものは、is演算子です。is演算子は

(expression) is (type)

のように使用し、(expression)がnullでなく、(expression)を(type)にキャストできる場合にtrueを返します。is演算子は参照変換、ボックス化変換、ボックス化解除変換だけを考慮し、ユーザー定義変換などの変換は、考慮しません。(TypeOf...Is式も同様だと思いますが、詳しくは分かりません。)

また、is演算子と同様の使い方でas演算子を使う場合もあります。as演算子は型の変換を実行しますが、キャストと違い、変換できなかった時に例外を発生せずにnullを返すため、nullを返したかを調べることにより、型の互換性を調べることができます。ただし、as演算子は参照変換とボックス化変換だけを実行し、ユーザー定義変換などの変換は実行できません。

なお、ユーザー定義変換も考慮して調べるには、キャストして例外が発生するか調べることになるでしょう。


C#でCreateObjectと同じことをするには?

C#でVB.NETのCreateObject関数と同じことをするには、Type.GetTypeFromProgIdメソッドで型を取得し、Activator.CreateInstanceメソッドなどによりインスタンスを作成します。

次にVB.NETのCreateObject関数とほぼ同様の機能を有するメソッドのコードを示します。

[C#]
/// <summary>
/// COMオブジェクトへの参照を作成および取得する
/// </summary>
/// <param name="progId">作成するオブジェクトのプログラムID</param>
/// <param name="serverName">
/// オブジェクトが作成されるネットワーク サーバーの名前
/// </param>
/// <returns>作成されたCOMオブジェクト</returns>
public static object CreateObject(string progId, string serverName)
{
    Type t;
    if (serverName == null || serverName.Length == 0)
        t = Type.GetTypeFromProgID(progId);
    else
        t = Type.GetTypeFromProgID(progId, serverName, true);
    return Activator.CreateInstance(t);
}

/// <summary>
/// COMオブジェクトへの参照を作成および取得する
/// </summary>
/// <param name="progId">作成するオブジェクトのプログラムID</param>
/// <returns>作成されたCOMオブジェクト</returns>
public static object CreateObject(string progId)
{
    return CreateObject(progId, null);
}

ただし、C#ではVB.NETと違い、暗黙の遅延バインディングができませんので、取得したCOMオブジェクトのプロパティやメソッドを呼び出すには、Type.InvokeMemberメソッドを使用する必要があります。詳しくは、こちらをご覧ください。


C#でSplit関数の代わりになるものは?

StringクラスのSplitメソッドは区切り文字としてChar型でしか指定できないため、文字列で区切り文字を指定できるVBのSplit関数とは大きく異なります。ではVBのSplit関数のように区切り文字を文字列(string型)で指定できるようにするにはどうすればよいのでしょうか?

これにはMicrosoft.VisualBasic.StringsクラスのSplitメソッドを使う方法と、Regexクラス(System.Text.RegularExpression名前空間)のSplitメソッドを使う方法が考えられます。しかしこれらはかなり処理速度が遅いです。分割したい文字列内の区切り文字(列)をいったん適当な1文字(分割したい文字列内の分割したくない位置に絶対現れることのない文字)に置換した後、StringクラスのSplitメソッドにより分割した方が圧倒的に速いケースも多いようです。

次のサンプルではRegex.Split、VisualBasic.Strings.Split、string.Splitそれぞれのメソッドを使ってstring型データを改行文字列("\r\n")で分割したときにかかった時間を計っています。

[C#]
//いろいろな方法でstring型データを改行文字列("\r\n")で分割し
//その時間を計る
//テキストファイルをstrTextに読み込む
string strFileName = "REDIST.TXT";
System.IO.FileStream fs = new System.IO.FileStream(strFileName,
    System.IO.FileMode.Open);
System.IO.StreamReader sr = new System.IO.StreamReader(fs, 
    System.Text.Encoding.GetEncoding(932));
string strText = sr.ReadToEnd();
sr.Close();

int t1, t2, t3;
string [] s1, s2, s3;

//Regex.Splitで分割する
t1 = System.Environment.TickCount;
s1 = System.Text.RegularExpressions.Regex.Split(strText,
    "\r\n");
t1 = System.Environment.TickCount - t1;

//VisualBasic.Strings.Splitで分割する
t2 = System.Environment.TickCount;
s2 = Microsoft.VisualBasic.Strings.Split(strText, "\r\n", -1,
    Microsoft.VisualBasic.CompareMethod.Binary);
t2 = System.Environment.TickCount - t2;

//string.Splitで分割する
t3 = System.Environment.TickCount;
s3 = strText.Replace("\r\n", "\n").Split('\n');;
t3 = System.Environment.TickCount - t3;

//結果を表示
Console.WriteLine("Regex.Split: {0}", t1);
Console.WriteLine("VisualBasic.Strings.Split: {0}", t2);
Console.WriteLine("string.Split: {0}", t3);
Console.WriteLine("Lines Count: {0}", s3.Length);

//表示例
//Regex.Split: 521
//VisualBasic.Strings.Split: 1452
//string.Split: 181

C#のイベント機能

VBでイベント機能を利用するには、イベントを発生させるクラスでEventステートメントによりイベントを宣言し、RaiseEventステートメントによりイベントを発生させ、イベントを受信するクラスではWithEventsで変数を宣言することなどにより簡単に可能となる。これと同様のことをC#で行うにはどのようにすればよいのだろうか。

これがVBほど簡単にはいかない。ヘルプなどを調べると「デリゲート」やら「イベントハンドラ」などの「?」な言葉が並ぶ。ここではこれらの理屈は抜きにしてこれらを実現させる簡単な方法を考えてみる。


最も簡単な(?)イベント

まず次のような超単純なクラス「SleepClass」を作ってみる。ここではまだイベントを使用していない。とりあえずStartメソッドを実行すると5秒間停止するだけである。

[C#]
public class SleepClass
{
    public void Start()
    {
        System.Threading.Thread.Sleep(5000);
    }
}

次に5秒停止後イベントが発生するようにしてみる。このときイベントが発生するだけで何もデータを返さないものとする。

[C#]
public class SleepClass
{
    // データを持たないイベントデリゲートの宣言
    //ここでは"Time"というイベントデリゲートを宣言する
    public event EventHandler Time;

    public void Start()
    {
        System.Threading.Thread.Sleep(5000);
        if (Time != null)
        {
            //"Time"イベントの発生
            Time(this, EventArgs.Empty);
        }
    }
}

イベントを受け取る側では次のように宣言する。ここではbutton1_ClickイベントによりSleepClassクラスのStartメソッドを呼び出し、イベント「Time」が発生するとSleepClass_Timeが呼び出され実行される。

[C#]
private void button1_Click(object sender, System.EventArgs e)
{
    SleepClass clsSleep = new SleepClass();
    //イベントハンドラの追加
    clsSleep.Time += new EventHandler(this.SleepClass_Time);
    clsSleep.Start();
}

private void SleepClass_Time(object sender, System.EventArgs e)
{
    //イベントが発生したとき
    MessageBox.Show("OK!");
}

ここでEventHandlerやEventArgsとは一体なんだろうという疑問が湧くだろうが、ここではあえてこれらの説明を省き、「こういうもの」としておこう。

これでほとんどの場合用が済んでしまうような気もするが、ヘルプにあるようにSleepClassを少し改良してみる。

[C#]
public class SleepClass
{
    // データを持たないイベントデリゲートの宣言
    public event EventHandler Time;

    protected virtual void OnTime(EventArgs e)
    {
        if (Time != null)
        {
            Time(this, e);
        }
    }

    public void Start()
    {
        System.Threading.Thread.Sleep(5000);
        OnTime(EventArgs.Empty);
    }
}

ここで変更された点といえばもちろん「protected virtual void OnTime(EventArgs e)」が追加されたことである。このSleepClassを継承して新たなクラスを作ることを考えればこうするべきということらしい。

以上説明はほとんどしなかったが、ここでの肝はすでに用意されているEventHandlerデリゲートと、EventArgsクラスを使ったことである。そのためにデリゲートの宣言と、返すデータのクラスを宣言する必要がなくなり、かなり簡略化ができた。しかしその分上記のような決まりきったやり方でしか使えないのが欠点といえる。


データを返すイベント

さて次はデータを返すイベントを作成する方法を考える。実は上記の例で使用した「EventHandlerデリゲート」と「EventArgsクラス」はイベントがデータを持たないから使えたわけで、そうでなければこれらに代わるものを自分で新しく用意する必要がある。

返されるデータは上の例の「EventArgs」に代わる(から継承される)クラスになるため、結局その部分だけを書き換えることになる。下にその例を示す。

[C#]
//Timeイベントで返されるデータ
//ここではstring型のひとつのデータのみ返すものとする
public class TimeEventArgs : EventArgs
{
    public string Message;
}

public class SleepClass
{
    //デリゲートの宣言
    //TimeEventArgs型のオブジェクトを返すようにする
    public delegate void TimeEventHandler(object sender, TimeEventArgs e);
    
    //イベントデリゲートの宣言
    public event TimeEventHandler Time;
    
    protected virtual void OnTime(TimeEventArgs e)
    {
        if (Time != null)
        {
            Time(this, e);
        }
    }
    
    public void Start()
    {
        System.Threading.Thread.Sleep(5000);
        //返すデータの設定
        TimeEventArgs e = new TimeEventArgs();
        e.Message = "終わったよ。";
        //イベントの発生
        OnTime(e);
    }
}

次は呼び出す側。

[C#]
private void button1_Click(object sender, System.EventArgs e)
{
    SleepClass clsSleep = new SleepClass();
    clsSleep.Time += new SleepClass.TimeEventHandler(this.SleepClass_Time);
    clsSleep.Start();
}

private void SleepClass_Time(object sender, TimeEventArgs e)
{
    //返されたデータを取得し表示
    MessageBox.Show(e.Message);
}

以上のようにデータを返さない単純なケースと比較して、返すデータを入れるTimeEventArgsクラスを使用するようにするための手間が余計に必要になる。ここで一番大事なのはイベントが発生したときに実行する関数(ここではSleepClass_Time)の2番目の引数の型が変更されることにより、以前使用していた「EventHandler」は使えなくなり、新しくデリゲートを宣言しなければいけないうところだろう。後は問題ないものと思う。


応用

いままではEventArgsの派生クラスを用いてデータを返していたが、必ずしもそうする必要はない。次の例ではEventArgsの派生クラスを使わずに文字列と整数を返しているが、やっていることは今までとまったく同じである。(ただし前に紹介したようなEventArgsの派生クラスを使った方法が.NETでは推奨された方法である。)

[C#]
public class SleepClass2
{
    //デリゲートの宣言
    public delegate void TimeEventHandler(string message, int number);
    //イベントデリゲートの宣言
    public event TimeEventHandler Time;

    protected virtual void OnTime(string message, int number)
    {
        if (Time != null)
        {
            Time(message, number);
        }
    }

    public void Start()
    {
        System.Threading.Thread.Sleep(5000);
        //イベントの発生
        OnTime("終わったっす。", 5000);
    }
}

使用する側では次のようになる。

[C#]
private void button1_Click(object sender, System.EventArgs e)
{
    SleepClass2 clsSleep = new SleepClass2();
    clsSleep.Time += new SleepClass2.TimeEventHandler(this.SleepClass2_Time);
    clsSleep.Start();
}

private void SleepClass2_Time(string message, int number)
{
    MessageBox.Show(message + ":" + number.ToString());
}

Collectionに代わるものは?

.NET Frameworkで用意されているコレクションクラスは、System.Collections名前空間にあります。この中から必要に応じて適当なクラスを選択して使用します。どのクラスを選択すべきかに関しては、ヘルプ「コレクション クラスの選択」で詳しく説明されています。

VBのCollectionに一番近いクラスは、.NET FrameworkではNameObjectCollectionBaseクラス (System.Collections.Specialized名前空間)であるようです。ただし、NameObjectCollectionBaseクラスは抽象クラスであるため、実際に使うためには派生クラスを作成しなければなりません。.NET FrameworkではNameObjectCollectionBaseクラスの派生クラスとして、NameValueCollectionクラスが用意されていますが、これは文字列のコレクションであり、同じキー名のアイテムを複数登録できるという違いがあります。

.NET Frameworkで実際によく使われるコレクションクラスは、ArrayListクラスか、Hashtableクラス(ともにSystem.Collections名前空間)です。ArrayListクラスはインデックスによってしか要素にアクセスできませんし、Hashtableクラスはキーによってしか要素にアクセスできません。


C#でReDim Preserveの代わりになるものは?

ここではVBの"ReDim Preserve"と同じことをC#で行うにはどうすればよいか考えてみましょう。

まず順当なのは、変更したいサイズの配列を新たに作成し、その配列に要素をコピーするという方法です。次に要素数を5から10に増やす例を示します。

[C#]
//要素数5の配列を作る
int[] intArray = {0, 1, 2, 3, 4};
//要素数10の配列を作る
int[] newArray = new int[10];
//配列の要素をコピーする
Array.Copy(intArray, newArray, 
    Math.Min(intArray.Length, newArray.Length));
//できた配列をintArrayに戻す
intArray = newArray;

バイト型配列の場合、配列の大きさを頻繁に変更するならば、MemoryStreamオブジェクトを使うと便利です。MemoryStreamオブジェクトのコンストラクタに基になるバイト型配列を指定できますが、この場合、指定されたバイト型配列のサイズ以上の容量にすることが出来なくなります。

MemoryStreamオブジェクトを使えば、下記の例のように、簡単にバイト型配列を追加したり、サイズを変更することができます。

[C#]
//MemoryStreamオブジェクトの作成
System.IO.MemoryStream ms = new System.IO.MemoryStream();

//バイト型配列をMemoryStreamに追加する
byte[] bs1 = new byte[] {0, 1, 2, 3, 4};
ms.Write(bs1, 0, bs1.Length);

//さらに追加する
byte[] bs2 = new byte[] {5, 6, 7};
ms.Write(bs2, 0, bs2.Length);

//MemoryStreamの大きさを変更する
ms.SetLength(10);

//MemoryStreamの内容をバイト型配列に変換する
byte[] bs = ms.ToArray();

//閉じる
ms.Close();

VB.NET、C#変換表

下の表ではVB.NETとC#とで同じ役割を果たしているであろうものをそれぞれを対応させて紹介しています。見やすくするため、分類のようなことをしていますが、これはかなりいい加減です。説明のほとんどはVB.NETの方のヘルプでの説明をのせています。

Visual Basic、Visual J#、C++、C#、JScriptの比較は、ヘルプの「各言語の比較」が参考になります。

Visual Basic .NET C# .NET 説明(ほとんどの場合VB.NETのヘルプより)
アクセス修飾子
Public public 宣言する 1 つ以上のプログラミング要素にパブリック アクセスを設定するキーワードです。パブリック アクセスを指定した要素のアクセシビリティには制約はありません。
Protected protected 宣言する 1 つ以上のプログラミング要素にプロテクト アクセスを設定するキーワードです。プロテクト アクセスを指定した要素には、そのクラス自体または派生クラスからだけアクセスできます。プロテクト アクセスはフレンド アクセスのスーパーセットではありません。
Friend internal 宣言する 1 つ以上のプログラミング要素にフレンド アクセスを設定するキーワードです。フレンド アクセスを指定した要素には、その宣言が含まれているプログラム、および同じアセンブリ内のその他の場所からアクセスできます。
Protected Friend protected internal 宣言される要素にはフレンド アクセスとプロテクト アクセスの両方が設定され、同じアセンブリ、要素自体のクラス、およびすべての派生クラスから要素にアクセスできます。
Private private 宣言する 1 つ以上のプログラミング要素にプライベート アクセスを設定するキーワードです。プライベート要素には、宣言コンテキストの中からだけアクセスできます。入れ子になったプロシージャの内部や入れ子になった列挙体の代入式の内部など、入れ子になった型のメンバからもアクセスできます。
修飾子
Shared static 宣言する 1 つ以上のプログラミング要素が共有されることを示すキーワードです。共有されている要素は、クラスや構造体の特定のインスタンスに関連付けられていません。共有されている要素にアクセスするには、クラス名や構造体名、またはクラスや構造体の特定のインスタンスの変数名を使用して修飾します。
Overridable virtual プロパティやメソッドを派生クラスでオーバーライドできることを示すキーワードです。
Overrides override プロパティやメソッドが基本クラスから継承したメンバをオーバーライドすることを示すキーワードです。
MustOverride abstract 派生クラスでオーバーライドしないと使用できない基本クラスのプロパティやプロシージャを示すキーワードです。
MustInherit abstract インスタンス化できず、基本クラスとしてだけ使用できるクラスを示すキーワードです。
NotOverridable sealed 派生クラスでオーバーライドできないプロパティまたはプロシージャを示すキーワードです。
NotInheritable sealed 基本クラスとして使用できないクラスを示すキーワードです。
Overloads (指定する必要なし) 名前は既存のメンバと同じでも、引数リストが元のメンバとは異なるプロパティやメソッドを宣言するキーワードです。
Shadows new 宣言したプログラミング要素が、基本クラスで同じ名前を持つ要素、またはオーバーロードされた要素のセットをシャドウすることを示すキーワードです。宣言された要素は、ほかの任意の種類の要素でシャドウできます。シャドウされた要素は、その要素をシャドウする派生クラスでは使用できません。
ByRef ref(呼び出し側で明示的に代入が必要)
out(呼び出される側で代入が必要)
引数を渡す方法としてキーワード ByRef を指定すると、呼び出されたプロシージャは、呼び出しコードの引数の基になる変数の値を変更できます。
クラス
New (クラスと同じ名前) クラスのコンストラクタ
Finalize ~(クラスと同じ名前) クラスのデストラクタ
Inherits class DerivedClass: BaseClass 現在のクラスまたはインターフェイスの属性、フィールド、プロパティ、メソッド、およびイベントを別のクラスまたはインターフェイスから継承します。
Implements class DerivedClass: BaseInterface インターフェイスが出現するクラスまたは構造体の定義に実装される、複数のインターフェイス、またはインターフェイス メンバを指定します。
演算子
GetType() typeof() 指定された型の型オブジェクトを返します。
Ctype () キャスト
Me this 実行される型のインスタンスを保持する変数への参照 (値型の場合) か、または実行される型のインスタンスへの直接参照 (参照型の場合) です。
MyBase base クラスの現在のインスタンスの基本クラスを参照するオブジェクト変数と同じように動作するキーワードです。
ステートメント
Import using 参照先のプロジェクトとアセンブリから名前空間の名前をインポートします。また、ステートメントを使用するファイルと同じプロジェクト内に定義された、名前空間の名前をインポートします。
Implements interface 現在のクラスまたはインターフェイスの属性、フィールド、プロパティ、メソッド、およびイベントを別のクラスまたはインターフェイスから継承します。
Structure struct 構造体を宣言してそのメンバの特性を定義するために、モジュール レベルまたはクラス レベルで使用します。
Property
Get
Set
Value
property
get
set
value
プロパティの値を設定および取得するためのプロパティ プロシージャ、およびプロパティの名前を宣言します。
Select Case 〜
Case 〜
Case Else 〜
End Select
switch(〜){
case 〜
default:〜
}
条件式の値に従って、複数のステートメント ブロックのいずれかを実行させるフロー制御ステートメントです。
SyncLock lock ステートメントを 1 つの式に同期させることができます。

C#でInputBox関数に代わるものは?

C#にVBのInputBox関数と同じものは用意されていません。つまりは自分でダイアログを作成するしかなさそうです。ダイアログフォームの作成方法はこちらの「フォームにOKボタン、キャンセルボタンを付ける」を参考にしてください。


文字列を記述する時"\"を"\\"と書くのが面倒なときは?

例えばString型の変数sに"C:\Dos\App\readme.txt"という文字列を代入したい時にVBでは

s = "C:\Dos\App\readme.txt"

と書くことが出来ますが、C#では次のように"\"を"\\"とする必要があります。

s = "C:\\Dos\\App\\readme.txt";

これはC#では"\"という文字があるとエスケープシーケンスが処理されてしまうためですが、これが面倒というケースもあります。そのような時は次のように@を付けることにより、エスケープシーケンスが処理されないように指定することができます。

s = @"C:\Dos\App\readme.txt";

このとき、"で囲まれた文字列の中に"という文字を入れるには、VBと同じように""と2回書きます。


C#でビープ音を鳴らす

VBではBeep関数により、簡単にビープ音(一般の警告音)を鳴らすことが出来ます。C#で同じようにビープ音を鳴らすには、Microsoft.VisualBasic名前空間内InteractionクラスのBeepメソッドを使うか、あるいはWin32 APIのMessageBeep関数を使います。

次にWin32 APIのMessageBeep関数でビープ音を鳴らす例を示します。

[C#]
//ビープ音を鳴らす
[System.Runtime.InteropServices.DllImport("user32.dll")] 
private static extern int MessageBeep(uint n); 
public static void Beep()
{
    MessageBeep(0);
}

C#でLike演算子の代わりになるものは?

C#にVBのLike演算子はありません。これと同等の処理をするには、Regexクラス(System.Text.RegularExpression名前空間)のIsMatchメソッドを使う方法(つまり正規表現を使う方法)があります。Like演算子の"*"、"?"、"#"はそれぞれ正規表現では".*"、"."、"\d"に置き換えることが出来ます。Like演算子の"[]"は正規表現でも"[]"で、Like演算子の"[!]"は正規表現では"[^]"と表現できます。

正規表現の"."は改行文字以外の文字を表すため、改行文字を含む文字列の比較では同一の結果とならないかもしれません。このような時は一致オプションにRegexOptions.Singlelineを指定し、単一行モードとします。このことにより、"."はすべての文字と一致するようになります。

さらに、Like演算子は2つの文字列が完全に一致するかを調べるのに対して、IsMatchメソッドは一致する箇所があるか調べるものです。よって、IsMatchメソッドでは検索パターン文字列の前後に"^"と"$"を付ける必要がありそうです。

当然ですが、検索パターン文字列に正規表現で使われるメタ文字が含まれているときは、これをエスケープしておかなければいけません。(これはRegex.Escapeメソッドを使ってできます。)

実際にこの変換を使用した例を下に示します。この例ではVBのLike演算子のヘルプでのサンプルをC#に変換してみました。

[C#]
//using System.Text.RegularExpressions;
//が宣言されているものとする

bool myCheck;

//myCheck = "F" Like "F"
myCheck = Regex.IsMatch("F", "^F$", RegexOptions.Singleline);
//myCheck: true

//myCheck = "F" Like "f"
myCheck = Regex.IsMatch("F", "^f$", RegexOptions.Singleline);
//myCheck: false

//myCheck = "F" Like "FFF"
myCheck = Regex.IsMatch("F", "^FFF$", RegexOptions.Singleline);
//myCheck: false

//myCheck = "aBBBa" Like "a*a"
myCheck =
    Regex.IsMatch("aBBBa", "^a.*a$", RegexOptions.Singleline);
//myCheck: true

//myCheck = "F" Like "[A-Z]"
myCheck =
    Regex.IsMatch("F", "^[A-Z]$", RegexOptions.Singleline);
//myCheck: true

//myCheck = "F" Like "[!A-Z]"
myCheck =
    Regex.IsMatch("F", "^[^A-Z]$", RegexOptions.Singleline);
//myCheck: false

//myCheck = "a2a" Like "a#a"
myCheck =
    Regex.IsMatch("a2a", "^a\\da$", RegexOptions.Singleline);
//myCheck: true

//myCheck = "aM5b" Like "a[L-P]#[!c-e]"
myCheck = Regex.IsMatch(
    "aM5b", "^a[L-P]\\d[^c-e]$", RegexOptions.Singleline);
//myCheck: true

//myCheck = "BAT123khg" Like "B?T*"
myCheck = Regex.IsMatch(
    "BAT123khg", "^B.T.*$", RegexOptions.Singleline);
//myCheck: true

//myCheck = "CAT123khg" Like "B?T*"
myCheck = Regex.IsMatch(
    "CAT123khg", "^B.T.*$", RegexOptions.Singleline);
//myCheck: false

Disposeメソッドが確実に呼び出されるようにする

C#にはDisposeメソッドを確実に呼び出すようにする簡単な方法が用意されています。それはusingステートメントを使う方法です。次の例ではFontクラスのインスタンスを作成し、その後クリーンアップしています。

[C#]
using System.Drawing;
class a
{
    public static void Main()
    {
        using (Font MyFont = new Font("Arial", 10.0f))
        {
            //MyFont を使用したコードがあるものとする
        }   //コンパイラが MyFont の Dispose を呼び出す

    }
}

これと同じものをVB.NETで書くと、Try...Finally文のFinallyにおいてDisposeメソッドを呼び出すことになります。

[VB.NET]
Imports System.Drawing
Class a
    Public Shared Sub Main()
        Dim MyFont As New Font("Arial", 10.0F)
        Try
            'MyFont を使用したコードがあるものとする
        Finally
            'MyFont の Dispose を呼び出す
            If Not MyFont Is Nothing Then
                MyFont.Dispose()
            End If
        End Try
    End Sub
End Class

IIf関数の代わりになるものは?

C#でVBのIIf関数と同じ機能を持ったものが?:演算子です(というかIIf関数が?:演算子のまねでしょうけど)。

VBの

s = IIf(i > 100, "Large", "Small")

はC#で次のようにかけます。

s = i > 100 ? "Large" : "Small";


メニューへ戻る


Copyright 2002-2005 DOBON!. All rights reserved.