1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Collections.Generic;
6 using System.Runtime.CompilerServices;
7 using Xunit;
8 
9 namespace System.Tests
10 {
11     public class ConvertBoxedObjectCheckTests
12     {
DefaultToTypeValues()13         public static IEnumerable<object[]> DefaultToTypeValues()
14         {
15             yield return new object[] { true };
16             yield return new object[] { false };
17             yield return new object[] { Byte.MinValue };
18             yield return new object[] { Byte.MaxValue };
19             yield return new object[] { SByte.MinValue };
20             yield return new object[] { SByte.MaxValue };
21             yield return new object[] { (SByte)0 };
22             yield return new object[] { Int16.MinValue };
23             yield return new object[] { Int16.MaxValue };
24             yield return new object[] { (Int16)0 };
25             yield return new object[] { UInt16.MinValue };
26             yield return new object[] { UInt16.MaxValue };
27             yield return new object[] { Int32.MinValue };
28             yield return new object[] { Int32.MaxValue };
29             yield return new object[] { (Int32)0 };
30             yield return new object[] { UInt32.MinValue };
31             yield return new object[] { UInt32.MaxValue };
32             yield return new object[] { Int64.MinValue };
33             yield return new object[] { Int64.MaxValue };
34             yield return new object[] { (Int64)0 };
35             yield return new object[] { UInt64.MinValue };
36             yield return new object[] { UInt64.MaxValue };
37             yield return new object[] { Char.MinValue };
38             yield return new object[] { Char.MaxValue };
39             yield return new object[] { (Char)0 };
40             yield return new object[] { Double.MinValue };
41             yield return new object[] { Double.MaxValue };
42             yield return new object[] { (Double)0 };
43             yield return new object[] { Single.MinValue };
44             yield return new object[] { Single.MaxValue };
45             yield return new object[] { (Single)0 };
46             yield return new object[] { Decimal.MinValue };
47             yield return new object[] { Decimal.MaxValue };
48             yield return new object[] { (Decimal)0 };
49             yield return new object[] { DateTime.MinValue };
50             yield return new object[] { DateTime.Now };
51             yield return new object[] { DateTime.MaxValue };
52         }
53 
54         [Theory]
55         [MemberData(nameof(DefaultToTypeValues))]
TestConvertedCopies(object testValue)56         public static void TestConvertedCopies(object testValue)
57         {
58             Assert.All(DefaultToTypeValues(), input =>
59             {
60                 try
61                 {
62                     object converted = ((IConvertible)testValue).ToType(input[0].GetType(), null);
63                     Assert.NotSame(testValue, converted);
64                 }
65                 catch (InvalidCastException) { }
66                 catch (OverflowException) { }
67             });
68         }
69 
70         [Theory]
71         [MemberData(nameof(DefaultToTypeValues))]
ChangeTypeIdentity(object testValue)72         public static void ChangeTypeIdentity(object testValue)
73         {
74             object copy = GetBoxedCopy(testValue);
75             Assert.NotSame(testValue, copy);
76             Assert.Equal(testValue, copy);
77         }
78 
GetBoxedCopy(object obj)79         public static object GetBoxedCopy(object obj)
80         {
81             Type type = obj.GetType();
82             if (type == typeof(Boolean))
83                 return Convert.ChangeType(obj, typeof(Boolean));
84             else if (type == typeof(Byte))
85                 return Convert.ChangeType(obj, typeof(Byte));
86             else if (type == typeof(SByte))
87                 return Convert.ChangeType(obj, typeof(SByte));
88             else if (type == typeof(Int16))
89                 return Convert.ChangeType(obj, typeof(Int16));
90             else if (type == typeof(Int32))
91                 return Convert.ChangeType(obj, typeof(Int32));
92             else if (type == typeof(Int64))
93                 return Convert.ChangeType(obj, typeof(Int64));
94             else if (type == typeof(UInt16))
95                 return Convert.ChangeType(obj, typeof(UInt16));
96             else if (type == typeof(UInt32))
97                 return Convert.ChangeType(obj, typeof(UInt32));
98             else if (type == typeof(UInt64))
99                 return Convert.ChangeType(obj, typeof(UInt64));
100             else if (type == typeof(IntPtr))
101                 return Convert.ChangeType(obj, typeof(IntPtr));
102             else if (type == typeof(UIntPtr))
103                 return Convert.ChangeType(obj, typeof(UIntPtr));
104             else if (type == typeof(Char))
105                 return Convert.ChangeType(obj, typeof(Char));
106             else if (type == typeof(Double))
107                 return Convert.ChangeType(obj, typeof(Double));
108             else if (type == typeof(Single))
109                 return Convert.ChangeType(obj, typeof(Single));
110             else if (type == typeof(Decimal))
111                 return Convert.ChangeType(obj, typeof(Decimal));
112             else
113                 // Not a primitive type
114                 return RuntimeHelpers.GetObjectValue(obj);
115         }
116     }
117 }
118