Add Unsafe.Unbox (dotnet/corefx#31133)
authorStephen Toub <stoub@microsoft.com>
Tue, 17 Jul 2018 20:46:50 +0000 (13:46 -0700)
committerGitHub <noreply@github.com>
Tue, 17 Jul 2018 20:46:50 +0000 (13:46 -0700)
Commit migrated from https://github.com/dotnet/corefx/commit/64c6d9fe5409be14bdc3609d73ffb3fea1f35797

src/libraries/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs
src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il
src/libraries/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml
src/libraries/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs

index 411b25e..b2f6ba8 100644 (file)
@@ -40,6 +40,7 @@ namespace System.Runtime.CompilerServices
         public static ref T Subtract<T>(ref T source, int elementOffset) { throw null; }
         public unsafe static void* Subtract<T>(void* source, int elementOffset) { throw null; }
         public static ref T Subtract<T>(ref T source, System.IntPtr elementOffset) { throw null; }
+        public static ref T Unbox<T>(object box) where T : struct { throw null; }
         public unsafe static void Write<T>(void* destination, T value) { }
         public unsafe static void WriteUnaligned<T>(void* destination, T value) { }
         public static void WriteUnaligned<T>(ref byte destination, T value) { }
index c8b3249..6ed086e 100644 (file)
         ret
   } // end of method Unsafe::As
 
+  .method public hidebysig static !!T& Unbox<valuetype .ctor ([CORE_ASSEMBLY]System.ValueType) T> (object 'box') cil managed aggressiveinlining
+  {
+        .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
+        .maxstack 1
+        ldarg.0
+        unbox !!T
+        ret
+  } // end of method Unsafe::Unbox
+
   .method public hidebysig static !!T& Add<T>(!!T& source, int32 elementOffset) cil managed aggressiveinlining
   {
         .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
index bb4911a..9918e2b 100644 (file)
             <param name="source">The reference to reinterpret.</param>
             <returns>A reference to a value of type <typeparamref name="TTo"/>.</returns>
         </member>
+        <member name="M:System.Runtime.CompilerServices.Unsafe.Unbox``1(System.Object)">
+            <summary>
+            Returns a reference to the value type contained with the specified box object.
+            </summary>
+            <typeparam name="T">The type of the value type contained within the box.</typeparam>
+            <param name="box">The boxed value type.</param>
+            <returns>A reference to a value of type <typeparamref name="T"/> in the box object.</returns>
+        </member>
         <member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(``0@,System.Int32)">
             <summary>
             Adds an element offset to the given reference.
index 821f8ac..1ad94ae 100644 (file)
@@ -793,6 +793,42 @@ namespace System.Runtime.CompilerServices
             Assert.Equal(123456789, actual.Int32);
             Assert.Equal(3.42, actual.Double);
         }
+
+        [Fact]
+        public static void Unbox_Int32()
+        {
+            object box = 42;
+
+            Assert.True(Unsafe.AreSame(ref Unsafe.Unbox<int>(box), ref Unsafe.Unbox<int>(box)));
+
+            Assert.Equal(42, (int)box);
+            Assert.Equal(42, Unsafe.Unbox<int>(box));
+
+            ref int value = ref Unsafe.Unbox<int>(box);
+            value = 84;
+            Assert.Equal(84, (int)box);
+            Assert.Equal(84, Unsafe.Unbox<int>(box));
+
+            Assert.Throws<InvalidCastException>(() => Unsafe.Unbox<Byte4>(box));
+        }
+
+        [Fact]
+        public static void Unbox_CustomValueType()
+        {
+            object box = new Int32Double();
+
+            Assert.Equal(0, ((Int32Double)box).Double);
+            Assert.Equal(0, ((Int32Double)box).Int32);
+
+            ref Int32Double value = ref Unsafe.Unbox<Int32Double>(box);
+            value.Double = 42;
+            value.Int32 = 84;
+
+            Assert.Equal(42, ((Int32Double)box).Double);
+            Assert.Equal(84, ((Int32Double)box).Int32);
+
+            Assert.Throws<InvalidCastException>(() => Unsafe.Unbox<bool>(box));
+        }
     }
 
     [StructLayout(LayoutKind.Explicit)]