invio / Invio.Immutable

C# Library used to ease immutable class creation and data management
MIT License
2 stars 0 forks source link

Incorrect type returned by GetPropertyValue for nullable properties #28

Closed sflanker closed 7 years ago

sflanker commented 7 years ago

Given this test:

        public static IEnumerable<Object[]> NullableValues { get; } =
            ImmutableList.Create(
                new Object[] { (DateTime?)null },
                new Object[] { (DateTime?)new DateTime(1934, 1, 11) });

        [Theory]
        [MemberData(nameof(NullableValues))]
        public void GetPropertyValueImpl_NullableProperty(DateTime? originalValue) {

            // Arrange

            var propertyName = nameof(Fake.NullableDateTime);
            var fake = this.NextFake().SetNullableDateTime(originalValue);

            // Act

            var value = fake.GetPropertyValue(propertyName);

            // Assert

            Assert.IsType<DateTime?>(value);
            Assert.Equal(originalValue, value);
        }

The following test failure occurs:

Failed   Invio.Immutable.PropertyValueImplTests.GetPropertyValueImpl_NullableProperty(originalValue: 1934-01-11T00:00:00.0000000)
Error Message:
 Assert.IsType() Failure
Expected: System.Nullable`1[[System.DateTime, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
Actual:   System.DateTime
Stack Trace:
   at Invio.Immutable.PropertyValueImplTests.GetPropertyValueImpl_NullableProperty(Nullable`1 originalValue) in /test/Invio.Immutable.Tests/PropertyValueImplTests.cs:line 208
Failed   Invio.Immutable.PropertyValueImplTests.GetPropertyValueImpl_NullableProperty(originalValue: null)
Error Message:
 Assert.IsType() Failure
Expected: System.Nullable`1[[System.DateTime, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
Actual:   (null)
Stack Trace:
   at Invio.Immutable.PropertyValueImplTests.GetPropertyValueImpl_NullableProperty(Nullable`1 originalValue) in /test/Invio.Immutable.Tests/PropertyValueImplTests.cs:line 208
sflanker commented 7 years ago

By design and/or a limitation (feature?) of the .Net framework. When Nullable structs are cast to Object (boxed) they type information (fact that they were Nullable) is lost and they are just stored as either a box integer or a null. Even this Int32? foo = 1; Console.WriteLine(foo.GetType().FullName)); displays "System.Int32" because calling GetType requires the struct to be boxed.