maxfie1d のブログ

マイクロソフト系技術ネタを中心に書きます。

C# の珍しいキーワード、unsafe

C# を使っていて、滅多にお目にかからないキーワードが存在します。

前回の checked/unchecked、implicit/explicit キーワードに引き続き、 今回は unsafe キーワードのお話です。

maxfie1d.hatenablog.com

maxfie1d.hatenablog.com

unsafe とは

C# では実は C/C++ のポインタ操作のようなことが出来ます。 ただしこの時unsafeキーワードを使う必要があります。

unsafe の使い方の例

unsafeキーワードはメソッドの定義に加えると、 メソッド内でポインタ操作を行うことが出来るようになります。

また、unsafeなメソッドを呼び出すメソッドもunsafeを付ける必要があります。

注意: unsafe を含むコードをコンパイルするには/unsafeオプションを指定する必要があります。 ソリューションエクスプローラーのプロジェクトを右クリックしてプロパティを開き ビルド(Build) > アンセーフコードの許可(Allow unsafe code) にチェックを入れます。 f:id:maxfieldwalker:20180117121825p:plain

// See: https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/unsafe
// /unsafeオプションでコンパイルします

class UnsafeTest
{
   // 安全でないメソッド: int へのポインタを引数に取ります
   unsafe static void SquarePtrParam(int* p)
   {
      *p *= *p;
   }

   unsafe static void Main()
   {
      int i = 5;
      // 安全でないメソッド: アドレス演算子を使います
      SquarePtrParam(&i);
      Console.WriteLine(i);
   }
}
// Output: 25

上記のコードを実行すると、25が出力されます。 変数i5が代入された後、SquarePtrParamメソッド内でポインタを介して値が書き換えられるというわけです。

また、unsafeはブロックにも使えます。 この場合ブロック内でのみポインタ操作が可能になります。

        static unsafe void Main(string[] args)
        {
            int i = 5;
            // unsafe ブロック
            unsafe
            {
                int* p = &i;
                *p *= *p;
            }
            Console.WriteLine(i);
            Console.ReadKey();
        }