{
Type elementType = JsonClassInfo.GetElementType(RuntimePropertyType);
+ // If the property type only has interface(s) exposed by JsonEnumerableT<T> then use JsonEnumerableT as the converter.
if (RuntimePropertyType.IsAssignableFrom(typeof(JsonEnumerableT<>).MakeGenericType(elementType)))
{
EnumerableConverter = s_jsonEnumerableConverter;
return (TAttribute)PropertyInfo?.GetCustomAttribute(typeof(TAttribute), inherit: false);
}
- internal abstract void Read(JsonTokenType tokenType, JsonSerializerOptions options, ref ReadStack state, ref Utf8JsonReader reader);
+ internal abstract void ApplyNullValue(JsonSerializerOptions options, ref ReadStack state);
+
+ internal abstract IList CreateConverterList();
+ internal abstract void Read(JsonTokenType tokenType, JsonSerializerOptions options, ref ReadStack state, ref Utf8JsonReader reader);
internal abstract void ReadEnumerable(JsonTokenType tokenType, JsonSerializerOptions options, ref ReadStack state, ref Utf8JsonReader reader);
internal abstract void SetValueAsObject(object obj, object value, JsonSerializerOptions options);
internal abstract void Write(JsonSerializerOptions options, ref WriteStackFrame current, ref Utf8JsonWriter writer);
-
internal abstract void WriteEnumerable(JsonSerializerOptions options, ref WriteStackFrame current, ref Utf8JsonWriter writer);
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text.Json.Serialization.Converters;
Set((TClass)obj, (TDeclaredProperty)value);
}
}
+
+ internal override IList CreateConverterList()
+ {
+ return new List<TDeclaredProperty>();
+ }
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
}
}
+ // If this method is changed, also change JsonPropertyInfoNullable.ReadEnumerable and JsonSerializer.ApplyObjectToEnumerable
internal override void ReadEnumerable(JsonTokenType tokenType, JsonSerializerOptions options, ref ReadStack state, ref Utf8JsonReader reader)
{
- if (ValueConverter != null)
+ if (ValueConverter == null || !ValueConverter.TryRead(RuntimePropertyType, ref reader, out TRuntimeProperty value))
{
- if (ValueConverter.TryRead(RuntimePropertyType, ref reader, out TRuntimeProperty value))
- {
- ReadStackFrame.SetReturnValue(value, options, ref state.Current);
- return;
- }
+ ThrowHelper.ThrowJsonReaderException_DeserializeUnableToConvertValue(RuntimePropertyType, reader, state);
+ return;
}
- ThrowHelper.ThrowJsonReaderException_DeserializeUnableToConvertValue(RuntimePropertyType, reader, state);
+ JsonSerializer.ApplyValueToEnumerable(ref value, options, ref state.Current);
+ }
+
+ internal override void ApplyNullValue(JsonSerializerOptions options, ref ReadStack state)
+ {
+ Debug.Assert(state.Current.JsonPropertyInfo != null);
+ state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, null, options);
}
// todo: have the caller check if current.Enumerator != null and call WriteEnumerable of the underlying property directly to avoid an extra virtual call.
if (ValueConverter != null)
{
Debug.Assert(current.Enumerator != null);
- TRuntimeProperty value = (TRuntimeProperty)current.Enumerator.Current;
+
+ TRuntimeProperty value;
+ if (current.Enumerator is IEnumerator<TRuntimeProperty> enumerator)
+ {
+ // Avoid boxing for strongly-typed enumerators such as returned from IList<T>.
+ value = enumerator.Current;
+ }
+ else
+ {
+ value = (TRuntimeProperty)current.Enumerator.Current;
+ }
+
if (value == null)
{
writer.WriteNullValue();
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
/// <summary>
/// Represents a strongly-typed property that is a <see cref="Nullable{T}"/>.
/// </summary>
- internal sealed class JsonPropertyInfoNullable<TClass, TProperty>
+ internal sealed class JsonPropertyInfoNullable<TClass, TProperty>
: JsonPropertyInfoCommon<TClass, TProperty?, TProperty>
where TProperty : struct
{
internal override void ReadEnumerable(JsonTokenType tokenType, JsonSerializerOptions options, ref ReadStack state, ref Utf8JsonReader reader)
{
- if (ValueConverter != null)
+ if (ValueConverter == null || !ValueConverter.TryRead(typeof(TProperty), ref reader, out TProperty value))
{
- if (ValueConverter.TryRead(s_underlyingType, ref reader, out TProperty value))
- {
- ReadStackFrame.SetReturnValue(value, options, ref state.Current);
- return;
- }
+ ThrowHelper.ThrowJsonReaderException_DeserializeUnableToConvertValue(RuntimePropertyType, reader, state);
+ return;
}
- ThrowHelper.ThrowJsonReaderException_DeserializeUnableToConvertValue(RuntimePropertyType, reader, state);
+ // Converting to TProperty? here lets us share a common ApplyValue() with ApplyNullValue().
+ TProperty? nullableValue = new TProperty?(value);
+ JsonSerializer.ApplyValueToEnumerable(ref nullableValue, options, ref state.Current);
+ }
+
+ internal override void ApplyNullValue(JsonSerializerOptions options, ref ReadStack state)
+ {
+ TProperty? nullableValue = null;
+ JsonSerializer.ApplyValueToEnumerable(ref nullableValue, options, ref state.Current);
}
// todo: have the caller check if current.Enumerator != null and call WriteEnumerable of the underlying property directly to avoid an extra virtual call.
if (ValueConverter != null)
{
Debug.Assert(current.Enumerator != null);
- TProperty? value = (TProperty?)current.Enumerator.Current;
+
+ TProperty? value;
+ if (current.Enumerator is IEnumerator<TProperty?> enumerator)
+ {
+ // Avoid boxing for strongly-typed enumerators such as returned from IList<T>.
+ value = enumerator.Current;
+ }
+ else
+ {
+ value = (TProperty?)current.Enumerator.Current;
+ }
+
if (value == null)
{
writer.WriteNullValue();
// See the LICENSE file in the project root for more information.
using System.Collections;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Json.Serialization.Policies;
// else there must be an outer object, so we'll return false here.
}
- ReadStackFrame.SetReturnValue(value, options, ref state.Current, setPropertyDirectly: setPropertyDirectly);
+ ApplyObjectToEnumerable(value, options, ref state.Current, setPropertyDirectly: setPropertyDirectly);
if (!valueReturning)
{
return false;
}
+
+ // If this method is changed, also change ApplyValueToEnumerable.
+ internal static void ApplyObjectToEnumerable(object value, JsonSerializerOptions options, ref ReadStackFrame frame, bool setPropertyDirectly = false)
+ {
+ if (frame.IsEnumerable())
+ {
+ if (frame.TempEnumerableValues != null)
+ {
+ frame.TempEnumerableValues.Add(value);
+ }
+ else
+ {
+ ((IList)frame.ReturnValue).Add(value);
+ }
+ }
+ else if (!setPropertyDirectly && frame.IsPropertyEnumerable())
+ {
+ Debug.Assert(frame.JsonPropertyInfo != null);
+ Debug.Assert(frame.ReturnValue != null);
+ if (frame.TempEnumerableValues != null)
+ {
+ frame.TempEnumerableValues.Add(value);
+ }
+ else
+ {
+ ((IList)frame.JsonPropertyInfo.GetValueAsObject(frame.ReturnValue, options)).Add(value);
+ }
+ }
+ else
+ {
+ Debug.Assert(frame.JsonPropertyInfo != null);
+ frame.JsonPropertyInfo.SetValueAsObject(frame.ReturnValue, value, options);
+ }
+ }
+
+ // If this method is changed, also change ApplyObjectToEnumerable.
+ internal static void ApplyValueToEnumerable<TProperty>(ref TProperty value, JsonSerializerOptions options, ref ReadStackFrame frame)
+ {
+ if (frame.IsEnumerable())
+ {
+ if (frame.TempEnumerableValues != null)
+ {
+ ((IList<TProperty>)frame.TempEnumerableValues).Add(value);
+ }
+ else
+ {
+ ((IList<TProperty>)frame.ReturnValue).Add(value);
+ }
+ }
+ else if (frame.IsPropertyEnumerable())
+ {
+ Debug.Assert(frame.JsonPropertyInfo != null);
+ Debug.Assert(frame.ReturnValue != null);
+ if (frame.TempEnumerableValues != null)
+ {
+ ((IList<TProperty>)frame.TempEnumerableValues).Add(value);
+ }
+ else
+ {
+ ((IList<TProperty>)frame.JsonPropertyInfo.GetValueAsObject(frame.ReturnValue, options)).Add(value);
+ }
+ }
+ else
+ {
+ Debug.Assert(frame.JsonPropertyInfo != null);
+ frame.JsonPropertyInfo.SetValueAsObject(frame.ReturnValue, value, options);
+ }
+ }
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections;
using System.Diagnostics;
namespace System.Text.Json.Serialization
ThrowHelper.ThrowJsonReaderException_DeserializeCannotBeNull(reader, state);
}
- if (state.Current.IsEnumerable() || state.Current.IsPropertyEnumerable())
+ if (state.Current.IsEnumerable())
{
- ReadStackFrame.SetReturnValue(null, options, ref state.Current);
+ ApplyObjectToEnumerable(null, options, ref state.Current);
+ return false;
+ }
+
+ if (state.Current.IsPropertyEnumerable())
+ {
+ state.Current.JsonPropertyInfo.ApplyNullValue(options, ref state);
return false;
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections;
+
namespace System.Text.Json.Serialization
{
public static partial class JsonSerializer
}
state.Pop();
- ReadStackFrame.SetReturnValue(value, options, ref state.Current);
+ ApplyObjectToEnumerable(value, options, ref state.Current);
return false;
}
}
if (state.Current.Enumerator == null)
{
+ IEnumerable enumerable = (IEnumerable)jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue, options);
+
+ if (enumerable == null)
+ {
+ // Write a null object or enumerable.
+ writer.WriteNull(jsonPropertyInfo._name);
+ return true;
+ }
+
+ state.Current.Enumerator = enumerable.GetEnumerator();
+
if (jsonPropertyInfo._name == null)
{
writer.WriteStartArray();
{
writer.WriteStartArray(jsonPropertyInfo._name);
}
-
- IEnumerable enumerable = (IEnumerable)jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue, options);
-
- if (enumerable != null)
- {
- state.Current.Enumerator = enumerable.GetEnumerator();
- }
}
- if (state.Current.Enumerator != null && state.Current.Enumerator.MoveNext())
+ if (state.Current.Enumerator.MoveNext())
{
// Check for polymorphism.
if (elementClassInfo.ClassType == ClassType.Unknown)
internal bool EnumerableCreated;
// Support System.Array and other types that don't implement IList
- internal List<object> TempEnumerableValues;
+ internal IList TempEnumerableValues;
// For performance, we order the properties by the first deserialize and PropertyIndex helps find the right slot quicker.
internal int PropertyIndex;
internal static object CreateEnumerableValue(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options)
{
+ JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo;
+
// If the property has an EnumerableConverter, then we use tempEnumerableValues.
- if (state.Current.JsonPropertyInfo.EnumerableConverter != null)
+ if (jsonPropertyInfo.EnumerableConverter != null)
{
- state.Current.TempEnumerableValues = new List<object>();
+ IList converterList;
+ if (jsonPropertyInfo.ElementClassInfo.ClassType == ClassType.Value)
+ {
+ converterList = jsonPropertyInfo.ElementClassInfo.GetPolicyProperty().CreateConverterList();
+ }
+ else
+ {
+ converterList = new List<object>();
+ }
+
+ state.Current.TempEnumerableValues = converterList;
+
return null;
}
Debug.Assert(ReturnValue == null);
ReturnValue = value;
}
-
- internal static void SetReturnValue(object value, JsonSerializerOptions options, ref ReadStackFrame current, bool setPropertyDirectly = false)
- {
- if (current.IsEnumerable())
- {
- if (current.TempEnumerableValues != null)
- {
- current.TempEnumerableValues.Add(value);
- }
- else
- {
- ((IList)current.ReturnValue).Add(value);
- }
- }
- else if (!setPropertyDirectly && current.IsPropertyEnumerable())
- {
- Debug.Assert(current.JsonPropertyInfo != null);
- Debug.Assert(current.ReturnValue != null);
- if (current.TempEnumerableValues != null)
- {
- current.TempEnumerableValues.Add(value);
- }
- else
- {
- ((IList)current.JsonPropertyInfo.GetValueAsObject(current.ReturnValue, options)).Add(value);
- }
- }
- else
- {
- Debug.Assert(current.JsonPropertyInfo != null);
- current.JsonPropertyInfo.SetValueAsObject(current.ReturnValue, value, options);
- }
- }
}
}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace System.Text.Json.Serialization.Tests
+{
+ public class SimpleTestClass : ITestClass
+ {
+ public short MyInt16 { get; set; }
+ public int MyInt32 { get; set; }
+ public long MyInt64 { get; set; }
+ public ushort MyUInt16 { get; set; }
+ public uint MyUInt32 { get; set; }
+ public ulong MyUInt64 { get; set; }
+ public byte MyByte { get; set; }
+ public sbyte MySByte { get; set; }
+ public char MyChar { get; set; }
+ public string MyString { get; set; }
+ public decimal MyDecimal { get; set; }
+ public bool MyBooleanTrue { get; set; }
+ public bool MyBooleanFalse { get; set; }
+ public float MySingle { get; set; }
+ public double MyDouble { get; set; }
+ public DateTime MyDateTime { get; set; }
+ public DateTimeOffset MyDateTimeOffset { get; set; }
+ public SampleEnum MyEnum { get; set; }
+ public short[] MyInt16Array { get; set; }
+ public int[] MyInt32Array { get; set; }
+ public long[] MyInt64Array { get; set; }
+ public ushort[] MyUInt16Array { get; set; }
+ public uint[] MyUInt32Array { get; set; }
+ public ulong[] MyUInt64Array { get; set; }
+ public byte[] MyByteArray { get; set; }
+ public sbyte[] MySByteArray { get; set; }
+ public char[] MyCharArray { get; set; }
+ public string[] MyStringArray { get; set; }
+ public decimal[] MyDecimalArray { get; set; }
+ public bool[] MyBooleanTrueArray { get; set; }
+ public bool[] MyBooleanFalseArray { get; set; }
+ public float[] MySingleArray { get; set; }
+ public double[] MyDoubleArray { get; set; }
+ public DateTime[] MyDateTimeArray { get; set; }
+ public DateTimeOffset[] MyDateTimeOffsetArray { get; set; }
+ public SampleEnum[] MyEnumArray { get; set; }
+ public List<string> MyStringList { get; set; }
+ public IEnumerable<string> MyStringIEnumerableT { get; set; }
+ public IList<string> MyStringIListT { get; set; }
+ public ICollection<string> MyStringICollectionT { get; set; }
+ public IReadOnlyCollection<string> MyStringIReadOnlyCollectionT { get; set; }
+ public IReadOnlyList<string> MyStringIReadOnlyListT { get; set; }
+
+ public static readonly string s_json = $"{{{s_partialJsonProperties},{s_partialJsonArrays}}}";
+ public static readonly string s_json_flipped = $"{{{s_partialJsonArrays},{s_partialJsonProperties}}}";
+
+ private const string s_partialJsonProperties =
+ @"""MyInt16"" : 1," +
+ @"""MyInt32"" : 2," +
+ @"""MyInt64"" : 3," +
+ @"""MyUInt16"" : 4," +
+ @"""MyUInt32"" : 5," +
+ @"""MyUInt64"" : 6," +
+ @"""MyByte"" : 7," +
+ @"""MySByte"" : 8," +
+ @"""MyChar"" : ""a""," +
+ @"""MyString"" : ""Hello""," +
+ @"""MyBooleanTrue"" : true," +
+ @"""MyBooleanFalse"" : false," +
+ @"""MySingle"" : 1.1," +
+ @"""MyDouble"" : 2.2," +
+ @"""MyDecimal"" : 3.3," +
+ @"""MyDateTime"" : ""2019-01-30T12:01:02.0000000Z""," +
+ @"""MyDateTimeOffset"" : ""2019-01-30T12:01:02.0000000+01:00""," +
+ @"""MyEnum"" : 2"; // int by default
+
+ private const string s_partialJsonArrays =
+ @"""MyInt16Array"" : [1]," +
+ @"""MyInt32Array"" : [2]," +
+ @"""MyInt64Array"" : [3]," +
+ @"""MyUInt16Array"" : [4]," +
+ @"""MyUInt32Array"" : [5]," +
+ @"""MyUInt64Array"" : [6]," +
+ @"""MyByteArray"" : [7]," +
+ @"""MySByteArray"" : [8]," +
+ @"""MyCharArray"" : [""a""]," +
+ @"""MyStringArray"" : [""Hello""]," +
+ @"""MyBooleanTrueArray"" : [true]," +
+ @"""MyBooleanFalseArray"" : [false]," +
+ @"""MySingleArray"" : [1.1]," +
+ @"""MyDoubleArray"" : [2.2]," +
+ @"""MyDecimalArray"" : [3.3]," +
+ @"""MyDateTimeArray"" : [""2019-01-30T12:01:02.0000000Z""]," +
+ @"""MyDateTimeOffsetArray"" : [""2019-01-30T12:01:02.0000000+01:00""]," +
+ @"""MyEnumArray"" : [2]," + // int by default
+ @"""MyStringList"" : [""Hello""]," +
+ @"""MyStringIEnumerableT"" : [""Hello""]," +
+ @"""MyStringIListT"" : [""Hello""]," +
+ @"""MyStringICollectionT"" : [""Hello""]," +
+ @"""MyStringIReadOnlyCollectionT"" : [""Hello""]," +
+ @"""MyStringIReadOnlyListT"" : [""Hello""]";
+
+ public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json);
+
+ public void Initialize()
+ {
+ MyInt16 = 1;
+ MyInt32 = 2;
+ MyInt64 = 3;
+ MyUInt16 = 4;
+ MyUInt32 = 5;
+ MyUInt64 = 6;
+ MyByte = 7;
+ MySByte = 8;
+ MyChar = 'a';
+ MyString = "Hello";
+ MyBooleanTrue = true;
+ MyBooleanFalse = false;
+ MySingle = 1.1f;
+ MyDouble = 2.2d;
+ MyDecimal = 3.3m;
+ MyDateTime = new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc);
+ MyDateTimeOffset = new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0));
+ MyEnum = SampleEnum.Two;
+
+ MyInt16Array = new short[] { 1 };
+ MyInt32Array = new int[] { 2 };
+ MyInt64Array = new long[] { 3 };
+ MyUInt16Array = new ushort[] { 4 };
+ MyUInt32Array = new uint[] { 5 };
+ MyUInt64Array = new ulong[] { 6 };
+ MyByteArray = new byte[] { 7 };
+ MySByteArray = new sbyte[] { 8 };
+ MyCharArray = new char[] { 'a' };
+ MyStringArray = new string[] { "Hello" };
+ MyBooleanTrueArray = new bool[] { true };
+ MyBooleanFalseArray = new bool[] { false };
+ MySingleArray = new float[] { 1.1f };
+ MyDoubleArray = new double[] { 2.2d };
+ MyDecimalArray = new decimal[] { 3.3m };
+ MyDateTimeArray = new DateTime[] { new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc) };
+ MyDateTimeOffsetArray = new DateTimeOffset[] { new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)) };
+ MyEnumArray = new SampleEnum[] { SampleEnum.Two };
+
+ MyStringList = new List<string>() { "Hello" };
+ MyStringIEnumerableT = new string[] { "Hello" };
+ MyStringIListT = new string[] { "Hello" };
+ MyStringICollectionT = new string[] { "Hello" };
+ MyStringIReadOnlyCollectionT = new string[] { "Hello" };
+ MyStringIReadOnlyListT = new string[] { "Hello" };
+ }
+
+ public void Verify()
+ {
+ Assert.Equal((short)1, MyInt16);
+ Assert.Equal((int)2, MyInt32);
+ Assert.Equal((long)3, MyInt64);
+ Assert.Equal((ushort)4, MyUInt16);
+ Assert.Equal((uint)5, MyUInt32);
+ Assert.Equal((ulong)6, MyUInt64);
+ Assert.Equal((byte)7, MyByte);
+ Assert.Equal((sbyte)8, MySByte);
+ Assert.Equal('a', MyChar);
+ Assert.Equal("Hello", MyString);
+ Assert.Equal(3.3m, MyDecimal);
+ Assert.Equal(false, MyBooleanFalse);
+ Assert.Equal(true, MyBooleanTrue);
+ Assert.Equal(1.1f, MySingle);
+ Assert.Equal(2.2d, MyDouble);
+ Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), MyDateTime);
+ Assert.Equal(new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)), MyDateTimeOffset);
+ Assert.Equal(SampleEnum.Two, MyEnum);
+
+ Assert.Equal((short)1, MyInt16Array[0]);
+ Assert.Equal((int)2, MyInt32Array[0]);
+ Assert.Equal((long)3, MyInt64Array[0]);
+ Assert.Equal((ushort)4, MyUInt16Array[0]);
+ Assert.Equal((uint)5, MyUInt32Array[0]);
+ Assert.Equal((ulong)6, MyUInt64Array[0]);
+ Assert.Equal((byte)7, MyByteArray[0]);
+ Assert.Equal((sbyte)8, MySByteArray[0]);
+ Assert.Equal('a', MyCharArray[0]);
+ Assert.Equal("Hello", MyStringArray[0]);
+ Assert.Equal(3.3m, MyDecimalArray[0]);
+ Assert.Equal(false, MyBooleanFalseArray[0]);
+ Assert.Equal(true, MyBooleanTrueArray[0]);
+ Assert.Equal(1.1f, MySingleArray[0]);
+ Assert.Equal(2.2d, MyDoubleArray[0]);
+ Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), MyDateTimeArray[0]);
+ Assert.Equal(new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)), MyDateTimeOffsetArray[0]);
+ Assert.Equal(SampleEnum.Two, MyEnumArray[0]);
+
+ Assert.Equal("Hello", MyStringList[0]);
+ Assert.Equal("Hello", MyStringIEnumerableT.First());
+ Assert.Equal("Hello", MyStringIListT[0]);
+ Assert.Equal("Hello", MyStringICollectionT.First());
+ Assert.Equal("Hello", MyStringIReadOnlyCollectionT.First());
+ Assert.Equal("Hello", MyStringIReadOnlyListT[0]);
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Xunit;
+
+namespace System.Text.Json.Serialization.Tests
+{
+ public abstract class SimpleBaseClassWithNullables
+ {
+ public short? MyInt16 { get; set; }
+ public int? MyInt32 { get; set; }
+ public long? MyInt64 { get; set; }
+ public ushort? MyUInt16 { get; set; }
+ public uint? MyUInt32 { get; set; }
+ public ulong? MyUInt64 { get; set; }
+ public byte? MyByte { get; set; }
+ public sbyte? MySByte { get; set; }
+ public char? MyChar { get; set; }
+ public decimal? MyDecimal { get; set; }
+ public bool? MyBooleanTrue { get; set; }
+ public bool? MyBooleanFalse { get; set; }
+ public float? MySingle { get; set; }
+ public double? MyDouble { get; set; }
+ public DateTime? MyDateTime { get; set; }
+ public DateTimeOffset? MyDateTimeOffset { get; set; }
+ public SampleEnum? MyEnum { get; set; }
+ public short?[] MyInt16Array { get; set; }
+ public int?[] MyInt32Array { get; set; }
+ public long?[] MyInt64Array { get; set; }
+ public ushort?[] MyUInt16Array { get; set; }
+ public uint?[] MyUInt32Array { get; set; }
+ public ulong?[] MyUInt64Array { get; set; }
+ public byte?[] MyByteArray { get; set; }
+ public sbyte?[] MySByteArray { get; set; }
+ public char?[] MyCharArray { get; set; }
+ public decimal?[] MyDecimalArray { get; set; }
+ public bool?[] MyBooleanTrueArray { get; set; }
+ public bool?[] MyBooleanFalseArray { get; set; }
+ public float?[] MySingleArray { get; set; }
+ public double?[] MyDoubleArray { get; set; }
+ public DateTime?[] MyDateTimeArray { get; set; }
+ public DateTimeOffset?[] MyDateTimeOffsetArray { get; set; }
+ public SampleEnum?[] MyEnumArray { get; set; }
+ }
+
+ public class SimpleTestClassWithNulls : SimpleBaseClassWithNullables, ITestClass
+ {
+ public void Initialize()
+ {
+ }
+
+ public void Verify()
+ {
+ Assert.Null(MyInt16);
+ Assert.Null(MyInt32);
+ Assert.Null(MyInt64);
+ Assert.Null(MyUInt16);
+ Assert.Null(MyUInt32);
+ Assert.Null(MyUInt64);
+ Assert.Null(MyByte);
+ Assert.Null(MySByte);
+ Assert.Null(MyChar);
+ Assert.Null(MyDecimal);
+ Assert.Null(MyBooleanFalse);
+ Assert.Null(MyBooleanTrue);
+ Assert.Null(MySingle);
+ Assert.Null(MyDouble);
+ Assert.Null(MyDateTime);
+ Assert.Null(MyDateTimeOffset);
+ Assert.Null(MyEnum);
+
+ Assert.Null(MyInt16Array);
+ Assert.Null(MyInt32Array);
+ Assert.Null(MyInt64Array);
+ Assert.Null(MyUInt16Array);
+ Assert.Null(MyUInt32Array);
+ Assert.Null(MyUInt64Array);
+ Assert.Null(MyByteArray);
+ Assert.Null(MySByteArray);
+ Assert.Null(MyCharArray);
+ Assert.Null(MyDecimalArray);
+ Assert.Null(MyBooleanFalseArray);
+ Assert.Null(MyBooleanTrueArray);
+ Assert.Null(MySingleArray);
+ Assert.Null(MyDoubleArray);
+ Assert.Null(MyDateTimeArray);
+ Assert.Null(MyDateTimeOffsetArray);
+ Assert.Null(MyEnumArray);
+ }
+ public static readonly string s_json =
+ @"{" +
+ @"""MyInt16"" : null," +
+ @"""MyInt32"" : null," +
+ @"""MyInt64"" : null," +
+ @"""MyUInt16"" : null," +
+ @"""MyUInt32"" : null," +
+ @"""MyUInt64"" : null," +
+ @"""MyByte"" : null," +
+ @"""MySByte"" : null," +
+ @"""MyChar"" : null," +
+ @"""MyBooleanTrue"" : null," +
+ @"""MyBooleanFalse"" : null," +
+ @"""MySingle"" : null," +
+ @"""MyDouble"" : null," +
+ @"""MyDecimal"" : null," +
+ @"""MyDateTime"" : null," +
+ @"""MyDateTimeOffset"" : null," +
+ @"""MyEnum"" : null," +
+ @"""MyInt16Array"" : null," +
+ @"""MyInt32Array"" : null," +
+ @"""MyInt64Array"" : null," +
+ @"""MyUInt16Array"" : null," +
+ @"""MyUInt32Array"" : null," +
+ @"""MyUInt64Array"" : null," +
+ @"""MyByteArray"" : null," +
+ @"""MySByteArray"" : null," +
+ @"""MyCharArray"" : null," +
+ @"""MyBooleanTrueArray"" : null," +
+ @"""MyBooleanFalseArray"" : null," +
+ @"""MySingleArray"" : null," +
+ @"""MyDoubleArray"" : null," +
+ @"""MyDecimalArray"" : null," +
+ @"""MyDateTimeArray"" : null," +
+ @"""MyDateTimeOffsetArray"" : null," +
+ @"""MyEnumArray"" : null" +
+ @"}";
+
+ public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json);
+ }
+
+ public class SimpleTestClassWithNullables : SimpleBaseClassWithNullables, ITestClass
+ {
+ public static readonly string s_json =
+ @"{" +
+ @"""MyInt16"" : 1," +
+ @"""MyInt32"" : 2," +
+ @"""MyInt64"" : 3," +
+ @"""MyUInt16"" : 4," +
+ @"""MyUInt32"" : 5," +
+ @"""MyUInt64"" : 6," +
+ @"""MyByte"" : 7," +
+ @"""MySByte"" : 8," +
+ @"""MyChar"" : ""a""," +
+ @"""MyBooleanTrue"" : true," +
+ @"""MyBooleanFalse"" : false," +
+ @"""MySingle"" : 1.1," +
+ @"""MyDouble"" : 2.2," +
+ @"""MyDecimal"" : 3.3," +
+ @"""MyDateTime"" : ""2019-01-30T12:01:02.0000000Z""," +
+ @"""MyDateTimeOffset"" : ""2019-01-30T12:01:02.0000000+01:00""," +
+ @"""MyEnum"" : 2," +
+ @"""MyInt16Array"" : [1]," +
+ @"""MyInt32Array"" : [2]," +
+ @"""MyInt64Array"" : [3]," +
+ @"""MyUInt16Array"" : [4]," +
+ @"""MyUInt32Array"" : [5]," +
+ @"""MyUInt64Array"" : [6]," +
+ @"""MyByteArray"" : [7]," +
+ @"""MySByteArray"" : [8]," +
+ @"""MyCharArray"" : [""a""]," +
+ @"""MyBooleanTrueArray"" : [true]," +
+ @"""MyBooleanFalseArray"" : [false]," +
+ @"""MySingleArray"" : [1.1]," +
+ @"""MyDoubleArray"" : [2.2]," +
+ @"""MyDecimalArray"" : [3.3]," +
+ @"""MyDateTimeArray"" : [""2019-01-30T12:01:02.0000000Z""]," +
+ @"""MyDateTimeOffsetArray"" : [""2019-01-30T12:01:02.0000000+01:00""]," +
+ @"""MyEnumArray"" : [2]" +
+ @"}";
+
+ public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json);
+
+ public void Initialize()
+ {
+ MyInt16 = 1;
+ MyInt32 = 2;
+ MyInt64 = 3;
+ MyUInt16 = 4;
+ MyUInt32 = 5;
+ MyUInt64 = 6;
+ MyByte = 7;
+ MySByte = 8;
+ MyChar = 'a';
+ MyBooleanTrue = true;
+ MyBooleanFalse = false;
+ MySingle = 1.1f;
+ MyDouble = 2.2d;
+ MyDecimal = 3.3m;
+ MyDateTime = new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc);
+ MyDateTimeOffset = new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0));
+ MyEnum = SampleEnum.Two;
+
+ MyInt16Array = new short?[] { 1 };
+ MyInt32Array = new int?[] { 2 };
+ MyInt64Array = new long?[] { 3 };
+ MyUInt16Array = new ushort?[] { 4 };
+ MyUInt32Array = new uint?[] { 5 };
+ MyUInt64Array = new ulong?[] { 6 };
+ MyByteArray = new byte?[] { 7 };
+ MySByteArray = new sbyte?[] { 8 };
+ MyCharArray = new char?[] { 'a' };
+ MyBooleanTrueArray = new bool?[] { true };
+ MyBooleanFalseArray = new bool?[] { false };
+ MySingleArray = new float?[] { 1.1f };
+ MyDoubleArray = new double?[] { 2.2d };
+ MyDecimalArray = new decimal?[] { 3.3m };
+ MyDateTimeArray = new DateTime?[] { new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc) };
+ MyDateTimeOffsetArray = new DateTimeOffset?[] { new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)) };
+ MyEnumArray = new SampleEnum?[] { SampleEnum.Two };
+ }
+
+ public void Verify()
+ {
+ Assert.Equal(MyInt16, (short)1);
+ Assert.Equal(MyInt32, (int)2);
+ Assert.Equal(MyInt64, (long)3);
+ Assert.Equal(MyUInt16, (ushort)4);
+ Assert.Equal(MyUInt32, (uint)5);
+ Assert.Equal(MyUInt64, (ulong)6);
+ Assert.Equal(MyByte, (byte)7);
+ Assert.Equal(MySByte, (sbyte)8);
+ Assert.Equal(MyChar, 'a');
+ Assert.Equal(MyDecimal, 3.3m);
+ Assert.Equal(MyBooleanFalse, false);
+ Assert.Equal(MyBooleanTrue, true);
+ Assert.Equal(MySingle, 1.1f);
+ Assert.Equal(MyDouble, 2.2d);
+ Assert.Equal(MyDateTime, new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc));
+ Assert.Equal(MyDateTimeOffset, new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)));
+ Assert.Equal(MyEnum, SampleEnum.Two);
+
+ Assert.Equal((short)1, MyInt16Array[0]);
+ Assert.Equal((int)2, MyInt32Array[0]);
+ Assert.Equal((long)3, MyInt64Array[0]);
+ Assert.Equal((ushort)4, MyUInt16Array[0]);
+ Assert.Equal((uint)5, MyUInt32Array[0]);
+ Assert.Equal((ulong)6, MyUInt64Array[0]);
+ Assert.Equal((byte)7, MyByteArray[0]);
+ Assert.Equal((sbyte)8, MySByteArray[0]);
+ Assert.Equal('a', MyCharArray[0]);
+ Assert.Equal(3.3m, MyDecimalArray[0]);
+ Assert.Equal(false, MyBooleanFalseArray[0]);
+ Assert.Equal(true, MyBooleanTrueArray[0]);
+ Assert.Equal(1.1f, MySingleArray[0]);
+ Assert.Equal(2.2d, MyDoubleArray[0]);
+ Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), MyDateTimeArray[0]);
+ Assert.Equal(new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)), MyDateTimeOffsetArray[0]);
+ Assert.Equal(SampleEnum.Two, MyEnumArray[0]);
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace System.Text.Json.Serialization.Tests
+{
+ public class SimpleTestClassWithObject : ITestClass
+ {
+ public object MyInt16 { get; set; }
+ public object MyInt32 { get; set; }
+ public object MyInt64 { get; set; }
+ public object MyUInt16 { get; set; }
+ public object MyUInt32 { get; set; }
+ public object MyUInt64 { get; set; }
+ public object MyByte { get; set; }
+ public object MySByte { get; set; }
+ public object MyChar { get; set; }
+ public object MyString { get; set; }
+ public object MyDecimal { get; set; }
+ public object MyBooleanTrue { get; set; }
+ public object MyBooleanFalse { get; set; }
+ public object MySingle { get; set; }
+ public object MyDouble { get; set; }
+ public object MyDateTime { get; set; }
+ public object MyEnum { get; set; }
+ public object MyInt16Array { get; set; }
+ public object MyInt32Array { get; set; }
+ public object MyInt64Array { get; set; }
+ public object MyUInt16Array { get; set; }
+ public object MyUInt32Array { get; set; }
+ public object MyUInt64Array { get; set; }
+ public object MyByteArray { get; set; }
+ public object MySByteArray { get; set; }
+ public object MyCharArray { get; set; }
+ public object MyStringArray { get; set; }
+ public object MyDecimalArray { get; set; }
+ public object MyBooleanTrueArray { get; set; }
+ public object MyBooleanFalseArray { get; set; }
+ public object MySingleArray { get; set; }
+ public object MyDoubleArray { get; set; }
+ public object MyDateTimeArray { get; set; }
+ public object MyEnumArray { get; set; }
+ public object MyStringList { get; set; }
+ public object MyStringIEnumerableT { get; set; }
+ public object MyStringIListT { get; set; }
+ public object MyStringICollectionT { get; set; }
+ public object MyStringIReadOnlyCollectionT { get; set; }
+ public object MyStringIReadOnlyListT { get; set; }
+
+ public static readonly string s_json =
+ @"{" +
+ @"""MyInt16"" : 1," +
+ @"""MyInt32"" : 2," +
+ @"""MyInt64"" : 3," +
+ @"""MyUInt16"" : 4," +
+ @"""MyUInt32"" : 5," +
+ @"""MyUInt64"" : 6," +
+ @"""MyByte"" : 7," +
+ @"""MySByte"" : 8," +
+ @"""MyChar"" : ""a""," +
+ @"""MyString"" : ""Hello""," +
+ @"""MyBooleanTrue"" : true," +
+ @"""MyBooleanFalse"" : false," +
+ @"""MySingle"" : 1.1," +
+ @"""MyDouble"" : 2.2," +
+ @"""MyDecimal"" : 3.3," +
+ @"""MyDateTime"" : ""2019-01-30T12:01:02.0000000Z""," +
+ @"""MyEnum"" : 2," + // int by default
+ @"""MyInt16Array"" : [1]," +
+ @"""MyInt32Array"" : [2]," +
+ @"""MyInt64Array"" : [3]," +
+ @"""MyUInt16Array"" : [4]," +
+ @"""MyUInt32Array"" : [5]," +
+ @"""MyUInt64Array"" : [6]," +
+ @"""MyByteArray"" : [7]," +
+ @"""MySByteArray"" : [8]," +
+ @"""MyCharArray"" : [""a""]," +
+ @"""MyStringArray"" : [""Hello""]," +
+ @"""MyBooleanTrueArray"" : [true]," +
+ @"""MyBooleanFalseArray"" : [false]," +
+ @"""MySingleArray"" : [1.1]," +
+ @"""MyDoubleArray"" : [2.2]," +
+ @"""MyDecimalArray"" : [3.3]," +
+ @"""MyDateTimeArray"" : [""2019-01-30T12:01:02.0000000Z""]," +
+ @"""MyEnumArray"" : [2]," + // int by default
+ @"""MyStringList"" : [""Hello""]," +
+ @"""MyStringIEnumerableT"" : [""Hello""]," +
+ @"""MyStringIListT"" : [""Hello""]," +
+ @"""MyStringICollectionT"" : [""Hello""]," +
+ @"""MyStringIReadOnlyCollectionT"" : [""Hello""]," +
+ @"""MyStringIReadOnlyListT"" : [""Hello""]" +
+ @"}";
+
+ public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json);
+
+ public void Initialize()
+ {
+ MyInt16 = (short)1;
+ MyInt32 = (int)2;
+ MyInt64 = (long)3;
+ MyUInt16 = (ushort)4;
+ MyUInt32 = (uint)5;
+ MyUInt64 = (ulong)6;
+ MyByte = (byte)7;
+ MySByte = (sbyte)8;
+ MyChar = 'a';
+ MyString = "Hello";
+ MyBooleanTrue = true;
+ MyBooleanFalse = false;
+ MySingle = 1.1f;
+ MyDouble = 2.2d;
+ MyDecimal = 3.3m;
+ MyDateTime = new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc);
+ MyEnum = SampleEnum.Two;
+
+ MyInt16Array = new short[] { 1 };
+ MyInt32Array = new int[] { 2 };
+ MyInt64Array = new long[] { 3 };
+ MyUInt16Array = new ushort[] { 4 };
+ MyUInt32Array = new uint[] { 5 };
+ MyUInt64Array = new ulong[] { 6 };
+ MyByteArray = new byte[] { 7 };
+ MySByteArray = new sbyte[] { 8 };
+ MyCharArray = new char[] { 'a' };
+ MyStringArray = new string[] { "Hello" };
+ MyBooleanTrueArray = new bool[] { true };
+ MyBooleanFalseArray = new bool[] { false };
+ MySingleArray = new float[] { 1.1f };
+ MyDoubleArray = new double[] { 2.2d };
+ MyDecimalArray = new decimal[] { 3.3m };
+ MyDateTimeArray = new DateTime[] { new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc) };
+ MyEnumArray = new SampleEnum[] { SampleEnum.Two };
+
+ MyStringList = new List<string>() { "Hello" };
+ MyStringIEnumerableT = new string[] { "Hello" };
+ MyStringIListT = new string[] { "Hello" };
+ MyStringICollectionT = new string[] { "Hello" };
+ MyStringIReadOnlyCollectionT = new string[] { "Hello" };
+ MyStringIReadOnlyListT = new string[] { "Hello" };
+ }
+
+ public void Verify()
+ {
+ Assert.Equal((short)1, MyInt16);
+ Assert.Equal((int)2, MyInt32);
+ Assert.Equal((long)3, MyInt64);
+ Assert.Equal((ushort)4, MyUInt16);
+ Assert.Equal((uint)5, MyUInt32);
+ Assert.Equal((ulong)6, MyUInt64);
+ Assert.Equal((byte)7, MyByte);
+ Assert.Equal((sbyte)8, MySByte);
+ Assert.Equal('a', MyChar);
+ Assert.Equal("Hello", MyString);
+ Assert.Equal(3.3m, MyDecimal);
+ Assert.Equal(false, MyBooleanFalse);
+ Assert.Equal(true, MyBooleanTrue);
+ Assert.Equal(1.1f, MySingle);
+ Assert.Equal(2.2d, MyDouble);
+ Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), MyDateTime);
+ Assert.Equal(SampleEnum.Two, MyEnum);
+
+ Assert.Equal((short)1, ((short[])MyInt16Array)[0]);
+ Assert.Equal((int)2, ((int[])MyInt32Array)[0]);
+ Assert.Equal((long)3, ((long[])MyInt64Array)[0]);
+ Assert.Equal((ushort)4, ((ushort[])MyUInt16Array)[0]);
+ Assert.Equal((uint)5, ((uint[])MyUInt32Array)[0]);
+ Assert.Equal((ulong)6, ((ulong[])MyUInt64Array)[0]);
+ Assert.Equal((byte)7, ((byte[])MyByteArray)[0]);
+ Assert.Equal((sbyte)8, ((sbyte[])MySByteArray)[0]);
+ Assert.Equal('a', ((char[])MyCharArray)[0]);
+ Assert.Equal("Hello", ((string[])MyStringArray)[0]);
+ Assert.Equal(3.3m, ((decimal[])MyDecimalArray)[0]);
+ Assert.Equal(false, ((bool[])MyBooleanFalseArray)[0]);
+ Assert.Equal(true, ((bool[])MyBooleanTrueArray)[0]);
+ Assert.Equal(1.1f, ((float[])MySingleArray)[0]);
+ Assert.Equal(2.2d, ((double[])MyDoubleArray)[0]);
+ Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), ((DateTime[])MyDateTimeArray)[0]);
+ Assert.Equal(SampleEnum.Two, ((SampleEnum[])MyEnumArray)[0]);
+
+ Assert.Equal("Hello", ((List<string>)MyStringList)[0]);
+ Assert.Equal("Hello", ((IEnumerable<string>)MyStringIEnumerableT).First());
+ Assert.Equal("Hello", ((IList<string>)MyStringIListT)[0]);
+ Assert.Equal("Hello", ((ICollection<string>)MyStringICollectionT).First());
+ Assert.Equal("Hello", ((IReadOnlyCollection<string>)MyStringIReadOnlyCollectionT).First());
+ Assert.Equal("Hello", ((IReadOnlyList<string>)MyStringIReadOnlyListT)[0]);
+ }
+ }
+}
Two = 2
}
- public class SimpleTestClass : ITestClass
- {
- public short MyInt16 { get; set; }
- public int MyInt32 { get; set; }
- public long MyInt64 { get; set; }
- public ushort MyUInt16 { get; set; }
- public uint MyUInt32 { get; set; }
- public ulong MyUInt64 { get; set; }
- public byte MyByte { get; set; }
- public sbyte MySByte { get; set; }
- public char MyChar { get; set; }
- public string MyString { get; set; }
- public decimal MyDecimal { get; set; }
- public bool MyBooleanTrue { get; set; }
- public bool MyBooleanFalse { get; set; }
- public float MySingle { get; set; }
- public double MyDouble { get; set; }
- public DateTime MyDateTime { get; set; }
- public DateTimeOffset MyDateTimeOffset { get; set; }
- public SampleEnum MyEnum { get; set; }
- public short[] MyInt16Array { get; set; }
- public int[] MyInt32Array { get; set; }
- public long[] MyInt64Array { get; set; }
- public ushort[] MyUInt16Array { get; set; }
- public uint[] MyUInt32Array { get; set; }
- public ulong[] MyUInt64Array { get; set; }
- public byte[] MyByteArray { get; set; }
- public sbyte[] MySByteArray { get; set; }
- public char[] MyCharArray { get; set; }
- public string[] MyStringArray { get; set; }
- public decimal[] MyDecimalArray { get; set; }
- public bool[] MyBooleanTrueArray { get; set; }
- public bool[] MyBooleanFalseArray { get; set; }
- public float[] MySingleArray { get; set; }
- public double[] MyDoubleArray { get; set; }
- public DateTime[] MyDateTimeArray { get; set; }
- public DateTimeOffset[] MyDateTimeOffsetArray { get; set; }
- public SampleEnum[] MyEnumArray { get; set; }
- public List<string> MyStringList { get; set; }
- public IEnumerable<string> MyStringIEnumerableT { get; set; }
- public IList<string> MyStringIListT { get; set; }
- public ICollection<string> MyStringICollectionT { get; set; }
- public IReadOnlyCollection<string> MyStringIReadOnlyCollectionT { get; set; }
- public IReadOnlyList<string> MyStringIReadOnlyListT { get; set; }
-
- public static readonly string s_json = $"{{{s_partialJsonProperties},{s_partialJsonArrays}}}";
- public static readonly string s_json_flipped = $"{{{s_partialJsonArrays},{s_partialJsonProperties}}}";
-
- private const string s_partialJsonProperties =
- @"""MyInt16"" : 1," +
- @"""MyInt32"" : 2," +
- @"""MyInt64"" : 3," +
- @"""MyUInt16"" : 4," +
- @"""MyUInt32"" : 5," +
- @"""MyUInt64"" : 6," +
- @"""MyByte"" : 7," +
- @"""MySByte"" : 8," +
- @"""MyChar"" : ""a""," +
- @"""MyString"" : ""Hello""," +
- @"""MyBooleanTrue"" : true," +
- @"""MyBooleanFalse"" : false," +
- @"""MySingle"" : 1.1," +
- @"""MyDouble"" : 2.2," +
- @"""MyDecimal"" : 3.3," +
- @"""MyDateTime"" : ""2019-01-30T12:01:02.0000000Z""," +
- @"""MyDateTimeOffset"" : ""2019-01-30T12:01:02.0000000+01:00""," +
- @"""MyEnum"" : 2"; // int by default
-
- private const string s_partialJsonArrays =
- @"""MyInt16Array"" : [1]," +
- @"""MyInt32Array"" : [2]," +
- @"""MyInt64Array"" : [3]," +
- @"""MyUInt16Array"" : [4]," +
- @"""MyUInt32Array"" : [5]," +
- @"""MyUInt64Array"" : [6]," +
- @"""MyByteArray"" : [7]," +
- @"""MySByteArray"" : [8]," +
- @"""MyCharArray"" : [""a""]," +
- @"""MyStringArray"" : [""Hello""]," +
- @"""MyBooleanTrueArray"" : [true]," +
- @"""MyBooleanFalseArray"" : [false]," +
- @"""MySingleArray"" : [1.1]," +
- @"""MyDoubleArray"" : [2.2]," +
- @"""MyDecimalArray"" : [3.3]," +
- @"""MyDateTimeArray"" : [""2019-01-30T12:01:02.0000000Z""]," +
- @"""MyDateTimeOffsetArray"" : [""2019-01-30T12:01:02.0000000+01:00""]," +
- @"""MyEnumArray"" : [2]," + // int by default
- @"""MyStringList"" : [""Hello""]," +
- @"""MyStringIEnumerableT"" : [""Hello""]," +
- @"""MyStringIListT"" : [""Hello""]," +
- @"""MyStringICollectionT"" : [""Hello""]," +
- @"""MyStringIReadOnlyCollectionT"" : [""Hello""]," +
- @"""MyStringIReadOnlyListT"" : [""Hello""]";
-
- public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json);
-
- public void Initialize()
- {
- MyInt16 = 1;
- MyInt32 = 2;
- MyInt64 = 3;
- MyUInt16 = 4;
- MyUInt32 = 5;
- MyUInt64 = 6;
- MyByte = 7;
- MySByte = 8;
- MyChar = 'a';
- MyString = "Hello";
- MyBooleanTrue = true;
- MyBooleanFalse = false;
- MySingle = 1.1f;
- MyDouble = 2.2d;
- MyDecimal = 3.3m;
- MyDateTime = new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc);
- MyDateTimeOffset = new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0));
- MyEnum = SampleEnum.Two;
-
- MyInt16Array = new short[] { 1 };
- MyInt32Array = new int[] { 2 };
- MyInt64Array = new long[] { 3 };
- MyUInt16Array = new ushort[] { 4 };
- MyUInt32Array = new uint[] { 5 };
- MyUInt64Array = new ulong[] { 6 };
- MyByteArray = new byte[] { 7 };
- MySByteArray = new sbyte[] { 8 };
- MyCharArray = new char[] { 'a' };
- MyStringArray = new string[] { "Hello" };
- MyBooleanTrueArray = new bool[] { true };
- MyBooleanFalseArray = new bool[] { false };
- MySingleArray = new float[] { 1.1f };
- MyDoubleArray = new double[] { 2.2d };
- MyDecimalArray = new decimal[] { 3.3m };
- MyDateTimeArray = new DateTime[] { new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc) };
- MyDateTimeOffsetArray = new DateTimeOffset[] { new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)) };
- MyEnumArray = new SampleEnum[] { SampleEnum.Two };
-
- MyStringList = new List<string>() { "Hello" };
- MyStringIEnumerableT = new string[] { "Hello" };
- MyStringIListT = new string[] { "Hello" };
- MyStringICollectionT = new string[] { "Hello" };
- MyStringIReadOnlyCollectionT = new string[] { "Hello" };
- MyStringIReadOnlyListT = new string[] { "Hello" };
- }
-
- public void Verify()
- {
- Assert.Equal((short)1, MyInt16);
- Assert.Equal((int)2, MyInt32);
- Assert.Equal((long)3, MyInt64);
- Assert.Equal((ushort)4, MyUInt16);
- Assert.Equal((uint)5, MyUInt32);
- Assert.Equal((ulong)6, MyUInt64);
- Assert.Equal((byte)7, MyByte);
- Assert.Equal((sbyte)8, MySByte);
- Assert.Equal('a', MyChar);
- Assert.Equal("Hello", MyString);
- Assert.Equal(3.3m, MyDecimal);
- Assert.Equal(false, MyBooleanFalse);
- Assert.Equal(true, MyBooleanTrue);
- Assert.Equal(1.1f, MySingle);
- Assert.Equal(2.2d, MyDouble);
- Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), MyDateTime);
- Assert.Equal(new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)), MyDateTimeOffset);
- Assert.Equal(SampleEnum.Two, MyEnum);
-
- Assert.Equal((short)1, MyInt16Array[0]);
- Assert.Equal((int)2, MyInt32Array[0]);
- Assert.Equal((long)3, MyInt64Array[0]);
- Assert.Equal((ushort)4, MyUInt16Array[0]);
- Assert.Equal((uint)5, MyUInt32Array[0]);
- Assert.Equal((ulong)6, MyUInt64Array[0]);
- Assert.Equal((byte)7, MyByteArray[0]);
- Assert.Equal((sbyte)8, MySByteArray[0]);
- Assert.Equal('a', MyCharArray[0]);
- Assert.Equal("Hello", MyStringArray[0]);
- Assert.Equal(3.3m, MyDecimalArray[0]);
- Assert.Equal(false, MyBooleanFalseArray[0]);
- Assert.Equal(true, MyBooleanTrueArray[0]);
- Assert.Equal(1.1f, MySingleArray[0]);
- Assert.Equal(2.2d, MyDoubleArray[0]);
- Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), MyDateTimeArray[0]);
- Assert.Equal(new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)), MyDateTimeOffsetArray[0]);
- Assert.Equal(SampleEnum.Two, MyEnumArray[0]);
-
- Assert.Equal("Hello", MyStringList[0]);
- Assert.Equal("Hello", MyStringIEnumerableT.First());
- Assert.Equal("Hello", MyStringIListT[0]);
- Assert.Equal("Hello", MyStringICollectionT.First());
- Assert.Equal("Hello", MyStringIReadOnlyCollectionT.First());
- Assert.Equal("Hello", MyStringIReadOnlyListT[0]);
- }
- }
-
- public class SimpleTestClassWithObject : ITestClass
- {
- public object MyInt16 { get; set; }
- public object MyInt32 { get; set; }
- public object MyInt64 { get; set; }
- public object MyUInt16 { get; set; }
- public object MyUInt32 { get; set; }
- public object MyUInt64 { get; set; }
- public object MyByte { get; set; }
- public object MySByte { get; set; }
- public object MyChar { get; set; }
- public object MyString { get; set; }
- public object MyDecimal { get; set; }
- public object MyBooleanTrue { get; set; }
- public object MyBooleanFalse { get; set; }
- public object MySingle { get; set; }
- public object MyDouble { get; set; }
- public object MyDateTime { get; set; }
- public object MyEnum { get; set; }
- public object MyInt16Array { get; set; }
- public object MyInt32Array { get; set; }
- public object MyInt64Array { get; set; }
- public object MyUInt16Array { get; set; }
- public object MyUInt32Array { get; set; }
- public object MyUInt64Array { get; set; }
- public object MyByteArray { get; set; }
- public object MySByteArray { get; set; }
- public object MyCharArray { get; set; }
- public object MyStringArray { get; set; }
- public object MyDecimalArray { get; set; }
- public object MyBooleanTrueArray { get; set; }
- public object MyBooleanFalseArray { get; set; }
- public object MySingleArray { get; set; }
- public object MyDoubleArray { get; set; }
- public object MyDateTimeArray { get; set; }
- public object MyEnumArray { get; set; }
- public object MyStringList { get; set; }
- public object MyStringIEnumerableT { get; set; }
- public object MyStringIListT { get; set; }
- public object MyStringICollectionT { get; set; }
- public object MyStringIReadOnlyCollectionT { get; set; }
- public object MyStringIReadOnlyListT { get; set; }
-
- public static readonly string s_json =
- @"{" +
- @"""MyInt16"" : 1," +
- @"""MyInt32"" : 2," +
- @"""MyInt64"" : 3," +
- @"""MyUInt16"" : 4," +
- @"""MyUInt32"" : 5," +
- @"""MyUInt64"" : 6," +
- @"""MyByte"" : 7," +
- @"""MySByte"" : 8," +
- @"""MyChar"" : ""a""," +
- @"""MyString"" : ""Hello""," +
- @"""MyBooleanTrue"" : true," +
- @"""MyBooleanFalse"" : false," +
- @"""MySingle"" : 1.1," +
- @"""MyDouble"" : 2.2," +
- @"""MyDecimal"" : 3.3," +
- @"""MyDateTime"" : ""2019-01-30T12:01:02.0000000Z""," +
- @"""MyEnum"" : 2," + // int by default
- @"""MyInt16Array"" : [1]," +
- @"""MyInt32Array"" : [2]," +
- @"""MyInt64Array"" : [3]," +
- @"""MyUInt16Array"" : [4]," +
- @"""MyUInt32Array"" : [5]," +
- @"""MyUInt64Array"" : [6]," +
- @"""MyByteArray"" : [7]," +
- @"""MySByteArray"" : [8]," +
- @"""MyCharArray"" : [""a""]," +
- @"""MyStringArray"" : [""Hello""]," +
- @"""MyBooleanTrueArray"" : [true]," +
- @"""MyBooleanFalseArray"" : [false]," +
- @"""MySingleArray"" : [1.1]," +
- @"""MyDoubleArray"" : [2.2]," +
- @"""MyDecimalArray"" : [3.3]," +
- @"""MyDateTimeArray"" : [""2019-01-30T12:01:02.0000000Z""]," +
- @"""MyEnumArray"" : [2]," + // int by default
- @"""MyStringList"" : [""Hello""]," +
- @"""MyStringIEnumerableT"" : [""Hello""]," +
- @"""MyStringIListT"" : [""Hello""]," +
- @"""MyStringICollectionT"" : [""Hello""]," +
- @"""MyStringIReadOnlyCollectionT"" : [""Hello""]," +
- @"""MyStringIReadOnlyListT"" : [""Hello""]" +
- @"}";
-
- public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json);
-
- public void Initialize()
- {
- MyInt16 = (short)1;
- MyInt32 = (int)2;
- MyInt64 = (long)3;
- MyUInt16 = (ushort)4;
- MyUInt32 = (uint)5;
- MyUInt64 = (ulong)6;
- MyByte = (byte)7;
- MySByte =(sbyte) 8;
- MyChar = 'a';
- MyString = "Hello";
- MyBooleanTrue = true;
- MyBooleanFalse = false;
- MySingle = 1.1f;
- MyDouble = 2.2d;
- MyDecimal = 3.3m;
- MyDateTime = new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc);
- MyEnum = SampleEnum.Two;
-
- MyInt16Array = new short[] { 1 };
- MyInt32Array = new int[] { 2 };
- MyInt64Array = new long[] { 3 };
- MyUInt16Array = new ushort[] { 4 };
- MyUInt32Array = new uint[] { 5 };
- MyUInt64Array = new ulong[] { 6 };
- MyByteArray = new byte[] { 7 };
- MySByteArray = new sbyte[] { 8 };
- MyCharArray = new char[] { 'a' };
- MyStringArray = new string[] { "Hello" };
- MyBooleanTrueArray = new bool[] { true };
- MyBooleanFalseArray = new bool[] { false };
- MySingleArray = new float[] { 1.1f };
- MyDoubleArray = new double[] { 2.2d };
- MyDecimalArray = new decimal[] { 3.3m };
- MyDateTimeArray = new DateTime[] { new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc) };
- MyEnumArray = new SampleEnum[] { SampleEnum.Two };
-
- MyStringList = new List<string>() { "Hello" };
- MyStringIEnumerableT = new string[] { "Hello" };
- MyStringIListT = new string[] { "Hello" };
- MyStringICollectionT = new string[] { "Hello" };
- MyStringIReadOnlyCollectionT = new string[] { "Hello" };
- MyStringIReadOnlyListT = new string[] { "Hello" };
- }
-
- public void Verify()
- {
- Assert.Equal((short)1, MyInt16);
- Assert.Equal((int)2, MyInt32);
- Assert.Equal((long)3, MyInt64);
- Assert.Equal((ushort)4, MyUInt16);
- Assert.Equal((uint)5, MyUInt32);
- Assert.Equal((ulong)6, MyUInt64);
- Assert.Equal((byte)7, MyByte);
- Assert.Equal((sbyte)8, MySByte);
- Assert.Equal('a', MyChar);
- Assert.Equal("Hello", MyString);
- Assert.Equal(3.3m, MyDecimal);
- Assert.Equal(false, MyBooleanFalse);
- Assert.Equal(true, MyBooleanTrue);
- Assert.Equal(1.1f, MySingle);
- Assert.Equal(2.2d, MyDouble);
- Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), MyDateTime);
- Assert.Equal(SampleEnum.Two, MyEnum);
-
- Assert.Equal((short)1, ((short[])MyInt16Array)[0]);
- Assert.Equal((int)2, ((int[])MyInt32Array)[0]);
- Assert.Equal((long)3, ((long[])MyInt64Array)[0]);
- Assert.Equal((ushort)4, ((ushort[])MyUInt16Array)[0]);
- Assert.Equal((uint)5, ((uint[])MyUInt32Array)[0]);
- Assert.Equal((ulong)6, ((ulong[])MyUInt64Array)[0]);
- Assert.Equal((byte)7, ((byte[])MyByteArray)[0]);
- Assert.Equal((sbyte)8, ((sbyte[])MySByteArray)[0]);
- Assert.Equal('a', ((char[])MyCharArray)[0]);
- Assert.Equal("Hello", ((string[])MyStringArray)[0]);
- Assert.Equal(3.3m, ((decimal[])MyDecimalArray)[0]);
- Assert.Equal(false, ((bool[])MyBooleanFalseArray)[0]);
- Assert.Equal(true, ((bool[])MyBooleanTrueArray)[0]);
- Assert.Equal(1.1f, ((float[])MySingleArray)[0]);
- Assert.Equal(2.2d, ((double[])MyDoubleArray)[0]);
- Assert.Equal(new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc), ((DateTime[])MyDateTimeArray)[0]);
- Assert.Equal(SampleEnum.Two, ((SampleEnum[])MyEnumArray)[0]);
-
- Assert.Equal("Hello", ((List<string>)MyStringList)[0]);
- Assert.Equal("Hello", ((IEnumerable<string>)MyStringIEnumerableT).First());
- Assert.Equal("Hello", ((IList<string>)MyStringIListT)[0]);
- Assert.Equal("Hello", ((ICollection<string>)MyStringICollectionT).First());
- Assert.Equal("Hello", ((IReadOnlyCollection<string>)MyStringIReadOnlyCollectionT).First());
- Assert.Equal("Hello", ((IReadOnlyList<string>)MyStringIReadOnlyListT)[0]);
- }
- }
-
- public abstract class SimpleBaseClassWithNullables
- {
- public short? MyInt16 { get; set; }
- public int? MyInt32 { get; set; }
- public long? MyInt64 { get; set; }
- public ushort? MyUInt16 { get; set; }
- public uint? MyUInt32 { get; set; }
- public ulong? MyUInt64 { get; set; }
- public byte? MyByte { get; set; }
- public sbyte? MySByte { get; set; }
- public char? MyChar { get; set; }
- public decimal? MyDecimal { get; set; }
- public bool? MyBooleanTrue { get; set; }
- public bool? MyBooleanFalse { get; set; }
- public float? MySingle { get; set; }
- public double? MyDouble { get; set; }
- public DateTime? MyDateTime { get; set; }
- public DateTimeOffset? MyDateTimeOffset { get; set; }
- public SampleEnum? MyEnum { get; set; }
- }
-
- public class SimpleTestClassWithNulls : SimpleBaseClassWithNullables, ITestClass
- {
- public void Initialize()
- {
- }
-
- public void Verify()
- {
- Assert.Null(MyInt16);
- Assert.Null(MyInt32);
- Assert.Null(MyInt64);
- Assert.Null(MyUInt16);
- Assert.Null(MyUInt32);
- Assert.Null(MyUInt64);
- Assert.Null(MyByte);
- Assert.Null(MySByte);
- Assert.Null(MyChar);
- Assert.Null(MyDecimal);
- Assert.Null(MyBooleanFalse);
- Assert.Null(MyBooleanTrue);
- Assert.Null(MySingle);
- Assert.Null(MyDouble);
- Assert.Null(MyDateTime);
- Assert.Null(MyDateTimeOffset);
- Assert.Null(MyEnum);
- }
- public static readonly string s_json =
- @"{" +
- @"""MyInt16"" : null," +
- @"""MyInt32"" : null," +
- @"""MyInt64"" : null," +
- @"""MyUInt16"" : null," +
- @"""MyUInt32"" : null," +
- @"""MyUInt64"" : null," +
- @"""MyByte"" : null," +
- @"""MySByte"" : null," +
- @"""MyChar"" : null," +
- @"""MyBooleanTrue"" : null," +
- @"""MyBooleanFalse"" : null," +
- @"""MySingle"" : null," +
- @"""MyDouble"" : null," +
- @"""MyDecimal"" : null," +
- @"""MyDateTime"" : null," +
- @"""MyDateTimeOffset"" : null," +
- @"""MyEnum"" : null" +
- @"}";
-
- public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json);
- }
-
- public class SimpleTestClassWithNullables : SimpleBaseClassWithNullables, ITestClass
- {
- public static readonly string s_json =
- @"{" +
- @"""MyInt16"" : 1," +
- @"""MyInt32"" : 2," +
- @"""MyInt64"" : 3," +
- @"""MyUInt16"" : 4," +
- @"""MyUInt32"" : 5," +
- @"""MyUInt64"" : 6," +
- @"""MyByte"" : 7," +
- @"""MySByte"" : 8," +
- @"""MyChar"" : ""a""," +
- @"""MyBooleanTrue"" : true," +
- @"""MyBooleanFalse"" : false," +
- @"""MySingle"" : 1.1," +
- @"""MyDouble"" : 2.2," +
- @"""MyDecimal"" : 3.3," +
- @"""MyDateTime"" : ""2019-01-30T12:01:02.0000000Z""," +
- @"""MyDateTimeOffset"" : ""2019-01-30T12:01:02.0000000+01:00""," +
- @"""MyEnum"" : 2" + // int by default
- @"}";
-
- public static readonly byte[] s_data = Encoding.UTF8.GetBytes(s_json);
-
- public void Initialize()
- {
- MyInt16 = 1;
- MyInt32 = 2;
- MyInt64 = 3;
- MyUInt16 = 4;
- MyUInt32 = 5;
- MyUInt64 = 6;
- MyByte = 7;
- MySByte = 8;
- MyChar = 'a';
- MyBooleanTrue = true;
- MyBooleanFalse = false;
- MySingle = 1.1f;
- MyDouble = 2.2d;
- MyDecimal = 3.3m;
- MyDateTime = new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc);
- MyDateTimeOffset = new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0));
- MyEnum = SampleEnum.Two;
- }
-
- public void Verify()
- {
- Assert.Equal(MyInt16, (short)1);
- Assert.Equal(MyInt32, (int)2);
- Assert.Equal(MyInt64, (long)3);
- Assert.Equal(MyUInt16, (ushort)4);
- Assert.Equal(MyUInt32, (uint)5);
- Assert.Equal(MyUInt64, (ulong)6);
- Assert.Equal(MyByte, (byte)7);
- Assert.Equal(MySByte, (sbyte)8);
- Assert.Equal(MyChar, 'a');
- Assert.Equal(MyDecimal, 3.3m);
- Assert.Equal(MyBooleanFalse, false);
- Assert.Equal(MyBooleanTrue, true);
- Assert.Equal(MySingle, 1.1f);
- Assert.Equal(MyDouble, 2.2d);
- Assert.Equal(MyDateTime, new DateTime(2019, 1, 30, 12, 1, 2, DateTimeKind.Utc));
- Assert.Equal(MyDateTimeOffset, new DateTimeOffset(2019, 1, 30, 12, 1, 2, new TimeSpan(1, 0, 0)));
- Assert.Equal(MyEnum, SampleEnum.Two);
- }
- }
-
public class TestClassWithNull
{
public string MyString { get; set; }
<Compile Include="Serialization\Stream.WriteTests.cs" />
<Compile Include="Serialization\TestClasses.cs" />
<Compile Include="Serialization\TestClasses.Polymorphic.cs" />
+ <Compile Include="Serialization\TestClasses.SimpleTestClass.cs" />
+ <Compile Include="Serialization\TestClasses.SimpleTestClassWithNullables.cs" />
+ <Compile Include="Serialization\TestClasses.SimpleTestClassWithObject.cs" />
<Compile Include="Serialization\TestData.cs" />
<Compile Include="Serialization\Value.ReadTests.cs" />
<Compile Include="Serialization\Value.WriteTests.cs" />