ここではC#のボックス化(Boxing)について学習します。
C#には大きく値型と参照型がありますが、これに関連する話です。
関数(※1)を学んだことで、ついに値型と参照型の違いを知ることができます。ここではC#で最重要とも言える値型と参照型の違いを理解しましょう。 ※1現在の知識を踏まえて、ここではメソッドではなく関数と呼びます。 値型と参照型の復習 まずは値型と参照型について復習しましょう。この2つは値を保存する場所が大きなポイントになります。 値型 値型とは用意した領域に直接的に値を保存します。 参照型 参照型は値を別の領域に格納し、それを...
ボックス化(Boxing)とボックス化の解除(Unboxing)
ボックス化とは、値型を参照型にキャストすることを言います。
ボックス化の解除は、その逆で参照型を値型にキャストすることです。
ここではC#の型変換、キャストについて学びます。 キャスト (cast) キャストとは型変換のことです。ある型で定義された変数や値を別の型に変更することを言います。今の知識範囲だと全ての変換方法は必要ないので、最も基礎的な暗黙的キャストと明示的キャストを理解しましょう。 暗黙的キャスト これが最もシンプルな方法です。まずはサンプルコードを見てみましょう。 namespace Sample { internal class Program { ...
これ、単にキャストだけの話ではありません。
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#に関する学習コンテンツ
この記事は参考になりましたか?
コメント