C#の興味深い瞬間(ボクシングのアンボクシング)

この記事では、ボクシング/アンボクシングのあまり知られていない機能について簡単に説明します。

foreachに関する前の記事
配列に関する以前の記事

パックとアンパックについてのインタビューでの典型的な質問は次のとおりです-「このコードを実行するとどうなりますか、それが機能しない場合、それを修正する方法は?」。

テストコード:
object box = (int)42; long unbox = (long)box; 

答えは次のようになります-「展開するとき、最初の演算子はそれぞれ型キャストではなく型展開であり、パック形式の値の型に対応している必要があります。」

正解は次のとおりです。
 object box = (int)42; long unbox = (long)(int)box; 

これは通常正しい答えと考えられていますが、完全に正しいわけではありません...

ボックス化解除と列挙


あなたが彼に別の正しい選択肢を書くとき、人が驚きを想像してください。

2番目の正解:
 public enum EnumType { None } ... object box = (int)42; long unbox = (long)(EnumType)box; 

enumは基本型ではなく、それから継承するものではなく、基本型(ベース)を含む構造であることを思い出してください。 これは、.NETがそのようなアンパックを明示的にサポートしていることを示唆しています。 また、圧縮解除で明示的および暗黙的な変換演算子が使用されていないこと、およびIConvertibleインターフェイスとその型をエイリアン型から展開できないことを確認するのも簡単です。
列挙型を展開するとき、その基本型が使用され、次の展開は機能しません。

間違ったオプション:
 public enum EnumType : short { None } ... object box = (int)42; long unbox = (long)(EnumType)box; 

列挙型の展開は非常に弱いです。

列挙型からintをアンパックします。
 public enum EnumType { None } ... object box = EnumType.None; long unbox = (long)(int)box; 

ある列挙型から別の列挙型を展開します。
 public enum EnumType { None } public enum EnumType2 { None } ... object box = EnumType.None; long unbox = (long)(EnumType2)box; 

ボックス化解除およびヌル可能


展開は、Nullable型もサポートしますが、これはより論理的なようです。

Nullable型を通常から展開する:
 object box = (int)42; long unbox = (long)(int?)box; 

Nullableから通常の型を展開します。
 object box = (int?)42; long unbox = (long)(int)box; 

Nullableは、1つの一般化された値型を持つ構造であり、データとデータ存在フラグを格納するように設計されていることを思い出させてください。 これは、C#がNullable型の圧縮解除を明示的にサポートしていることを示しています。 C#の新しいバージョンでは、この構造にエイリアス「?」が表示されました。

Nullable:
 public struct Nullable<T> where T : struct { public bool HasValue { get; } public T Value { get; } } 

同等のエントリ:
 Nullable<int> value; int? value; 

ご清聴ありがとうございました!

Source: https://habr.com/ru/post/J239219/


All Articles