安全なコードと安全でないコード (C# と Java の比較)
更新 : 2007 年 11 月
C# には、タイプ セーフでないコードをサポートするという興味深い特徴があります。通常は、共通言語ランタイム (CLR) が Microsoft Intermediate Language (MSIL) コードの動作を監視し、問題のありそうな動作を回避しますが、Win32 API 呼び出しなどの下位の機能に直接アクセスする必要があるときもあり、そのようなコードが正常に動作することを確信できる場合のみ、これを行うことができます。そのようなコードは、ソース コード内の unsafe ブロックの中に配置する必要があります。
unsafe キーワード
C# では、下位の API 呼び出しを行ったり、ポインタ演算を使用したりするような安全性に劣る操作を実行するコードは、unsafe キーワードでマークされたブロックの中に配置する必要があります。次の要素はいずれも unsafe とマークできます。
メソッド全体
中かっこ内のコード ブロック
個別のステートメント
上の 3 つのケースで unsafe を使用するコード例を次に示します。
class TestUnsafe
{
unsafe static void PointyMethod()
{
int i=10;
int *p = &i;
System.Console.WriteLine("*p = " + *p);
System.Console.WriteLine("Address of p = {0:X2}\n", (int)p);
}
static void StillPointy()
{
int i=10;
unsafe
{
int *p = &i;
System.Console.WriteLine("*p = " + *p);
System.Console.WriteLine("Address of p = {0:X2}\n", (int)p);
}
}
static void Main()
{
PointyMethod();
StillPointy();
}
}
このコードでは、PointyMethod() メソッド全体を unsafe とマークしていますが、それは、このメソッドでポインタを宣言し、使用するためです。また、StillPointy() メソッドでコードのブロックを unsafe とマークしているのは、このブロックでもポインタを使用するためです。
fixed キーワード
セーフ コードでは、ガベージ コレクタが、その有効期間中にオブジェクトを自由に移動し、フリー リソースを編成して凝縮します。ただし、コードでポインタを使用する場合は、この動作が原因で、予測できない結果が生じやすくなります。そのため、fixed ステートメントを使用して、ガベージ コレクタが特定のオブジェクトを移動しないように指示できます。
fixed キーワードを使用して、PointyMethod() メソッドのコード ブロックを実行しているときに配列が移動されないようにする例を次のコードに示します。fixed が、アンセーフ コードの中でしか使用されていないことに注意してください。
class TestFixed
{
public static void PointyMethod(char[] array)
{
unsafe
{
fixed (char *p = array)
{
for (int i=0; i<array.Length; i++)
{
System.Console.Write(*(p+i));
}
}
}
}
static void Main()
{
char[] array = { 'H', 'e', 'l', 'l', 'o' };
PointyMethod(array);
}
}
参照
処理手順
概念
参照
unsafe コードとポインタ (C# プログラミング ガイド)