ボックス化(Boxing)を理解しよう!

[C#] ボックス化(Boxing)を理解しよう!

※ 当サイトは広告を含みます。

ここではC#のボックス化(Boxing)について学習します。
C#には大きく値型と参照型がありますが、これに関連する話です。

ボックス化(Boxing)とボックス化の解除(Unboxing)

ボックス化とは、値型を参照型にキャストすることを言います。
ボックス化の解除は、その逆で参照型を値型にキャストすることです。

これ、単にキャストだけの話ではありません。

C#は全ての型がobject型を継承するため、どんな型でもobject型にアップキャストできます。
当然、その逆も然り。継承関係が正しい場合、object型はどんな型にもダウンキャストできます。
これは対象が値型でも同じです。値型とobject型もアップキャストまたはダウンキャストが可能です。

ただし、ここで問題があります。ここからは少しメモリ管理の知識が必要になるので超簡単に解説します。
C#では値型はスタック、参照型はヒープに確保されます。そしてスタックでメモリを確保するほうが早いです。

つまり、値型と参照型を経由したキャストを使うと、知らぬ間にコピーが発生します。
その処理は一般的に重い処理に分類され、基本的には回避したほうがいいです。

ボックス化(Boxing)

ボックス化は値型を参照型にキャストすることです。
この時、値はスタック領域からヒープ領域にコピーされます。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int i = 128;

      // ボックス化 (値型 => 参照型)
      object o = i;
    }
  }
}

なお、これは値がコピーされてるので、参照型を変更しても元々の値型には影響しません。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int i = 128;

      // ボックス化 (値型 => 参照型)
      object o = i;

      Console.WriteLine($"i={i}, o={o}");

      o = (int)1024;

      Console.WriteLine($"i={i}, o={o}");
    }
  }
}

Tips全ての型がobject型を継承するため、object型にキャストする場合は暗黙的キャストが可能です。

ボックス化の解除(Unboxing)

ボックス化の解除は参照型を値型にキャストすることです。
この時、値はヒープ領域からスタック領域にコピーされます。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      object o = 128;

      // ボックス化の解除 (参照型 => 値型)
      int i = (int)o;

      Console.WriteLine($"i={i}, o={o}");
    }
  }
}

こちらも値型と参照型がお互いに影響することはありません。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      object o = 128;

      // ボックス化の解除 (参照型 => 値型)
      int i = (int)o;

      Console.WriteLine($"i={i}, o={o}");

      o = 1024;

      Console.WriteLine($"i={i}, o={o}");
    }
  }
}

Tipsボックス化の解除はダウンキャストに該当するため、明示的キャストが必要です。

あとがき

追加でヒープ領域を確保するため、解除よりもボックス化の方が負荷が高いです。
ただ、普通は変換したら再変換もするので、両方のコストを考えたほうがいいです。

りさ

そんなに重いの?

管理人

公式が言うにはボックス化は最大20倍、解除は4倍だって。

公式ドキュメントhttps://learn.microsoft.com/en-us/dotnet/framework/performance/performance-tips#boxing-and-unboxing

◆ C#に関する学習コンテンツ

この記事は参考になりましたか?

関連記事

コメント

この記事へのコメントはありません。