diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs index 1bba7b41..d15be75a 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs @@ -2048,6 +2048,17 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual("goose", deserialized[2]); } +#if !(PORTABLE || PORTABLE40) + [Test] + public void DeserializeCultureInfoKey() + { + string json = @"{ ""en-US"": ""Hi"", ""sv-SE"": ""Hej"" }"; + + Dictionary values = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(2, values.Count); + } +#endif + public class MyClass : IList { private List _storage; diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index d28e854c..c7c528fa 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -423,8 +423,7 @@ namespace Newtonsoft.Json.Serialization } else if (Serializer.MetadataPropertyHandling == MetadataPropertyHandling.ReadAhead) { - JTokenReader tokenReader = reader as JTokenReader; - if (tokenReader == null) + if (!(reader is JTokenReader tokenReader)) { JToken t = JToken.ReadFrom(reader); tokenReader = (JTokenReader)t.CreateReader(); @@ -441,8 +440,7 @@ namespace Newtonsoft.Json.Serialization reader = tokenReader; } - object newValue; - if (ReadMetadataPropertiesToken(tokenReader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id)) + if (ReadMetadataPropertiesToken(tokenReader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out object newValue, out id)) { return newValue; } @@ -450,8 +448,7 @@ namespace Newtonsoft.Json.Serialization else { reader.ReadAndAssert(); - object newValue; - if (ReadMetadataProperties(reader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id)) + if (ReadMetadataProperties(reader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out object newValue, out id)) { return newValue; } @@ -518,8 +515,7 @@ namespace Newtonsoft.Json.Serialization if (existingValue == null) { - bool createdFromNonDefaultCreator; - IDictionary dictionary = CreateNewDictionary(reader, dictionaryContract, out createdFromNonDefaultCreator); + IDictionary dictionary = CreateNewDictionary(reader, dictionaryContract, out bool createdFromNonDefaultCreator); if (createdFromNonDefaultCreator) { @@ -626,7 +622,7 @@ namespace Newtonsoft.Json.Serialization if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) { - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Resolved object reference '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, reference, newValue.GetType())), null); + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader, reader.Path, "Resolved object reference '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, reference, newValue.GetType())), null); } reader.Skip(); @@ -824,8 +820,7 @@ namespace Newtonsoft.Json.Serialization throw JsonSerializationException.Create(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); } - JsonArrayContract arrayContract = contract as JsonArrayContract; - if (arrayContract == null) + if (!(contract is JsonArrayContract arrayContract)) { string message = @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type '{0}' because the type requires a {1} to deserialize correctly." + Environment.NewLine + @"To fix this error either change the JSON to a {1} or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array." + Environment.NewLine; @@ -850,8 +845,7 @@ namespace Newtonsoft.Json.Serialization if (existingValue == null) { - bool createdFromNonDefaultCreator; - IList list = CreateNewList(reader, arrayContract, out createdFromNonDefaultCreator); + IList list = CreateNewList(reader, arrayContract, out bool createdFromNonDefaultCreator); if (createdFromNonDefaultCreator) { @@ -970,9 +964,9 @@ namespace Newtonsoft.Json.Serialization } #if HAVE_BIG_INTEGER - if (value is BigInteger) + if (value is BigInteger integer) { - return ConvertUtils.FromBigInteger((BigInteger)value, contract.NonNullableUnderlyingType); + return ConvertUtils.FromBigInteger(integer, contract.NonNullableUnderlyingType); } #endif @@ -993,12 +987,7 @@ namespace Newtonsoft.Json.Serialization private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target) { - object currentValue; - bool useExistingValue; - JsonContract propertyContract; - bool gottenCurrentValue; - - if (CalculatePropertyDetails(property, ref propertyConverter, containerContract, containerProperty, reader, target, out useExistingValue, out currentValue, out propertyContract, out gottenCurrentValue)) + if (CalculatePropertyDetails(property, ref propertyConverter, containerContract, containerProperty, reader, target, out bool useExistingValue, out object currentValue, out JsonContract propertyContract, out bool gottenCurrentValue)) { return false; } @@ -1300,8 +1289,7 @@ namespace Newtonsoft.Json.Serialization private object PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id) { - IWrappedDictionary wrappedDictionary = dictionary as IWrappedDictionary; - object underlyingDictionary = wrappedDictionary != null ? wrappedDictionary.UnderlyingDictionary : dictionary; + object underlyingDictionary = dictionary is IWrappedDictionary wrappedDictionary ? wrappedDictionary.UnderlyingDictionary : dictionary; if (id != null) { @@ -1323,8 +1311,7 @@ namespace Newtonsoft.Json.Serialization } JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty); - JsonPrimitiveContract keyContract = contract.KeyContract as JsonPrimitiveContract; - PrimitiveTypeCode keyTypeCode = (keyContract != null) ? keyContract.TypeCode : PrimitiveTypeCode.Empty; + PrimitiveTypeCode keyTypeCode = (contract.KeyContract is JsonPrimitiveContract keyContract) ? keyContract.TypeCode : PrimitiveTypeCode.Empty; bool finished = false; do @@ -1348,30 +1335,18 @@ namespace Newtonsoft.Json.Serialization case PrimitiveTypeCode.DateTime: case PrimitiveTypeCode.DateTimeNullable: { - DateTime dt; - if (DateTimeUtils.TryParseDateTime(keyValue.ToString(), reader.DateTimeZoneHandling, reader.DateFormatString, reader.Culture, out dt)) - { - keyValue = dt; - } - else - { - keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType); - } + keyValue = DateTimeUtils.TryParseDateTime(keyValue.ToString(), reader.DateTimeZoneHandling, reader.DateFormatString, reader.Culture, out DateTime dt) + ? dt + : EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType); break; } #if HAVE_DATE_TIME_OFFSET case PrimitiveTypeCode.DateTimeOffset: case PrimitiveTypeCode.DateTimeOffsetNullable: { - DateTimeOffset dt; - if (DateTimeUtils.TryParseDateTimeOffset(keyValue.ToString(), reader.DateFormatString, reader.Culture, out dt)) - { - keyValue = dt; - } - else - { - keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType); - } + keyValue = DateTimeUtils.TryParseDateTimeOffset(keyValue.ToString(), reader.DateFormatString, reader.Culture, out DateTimeOffset dt) + ? dt + : EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType); break; } #endif @@ -1583,8 +1558,7 @@ namespace Newtonsoft.Json.Serialization private object PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id) { - IWrappedCollection wrappedCollection = list as IWrappedCollection; - object underlyingList = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : list; + object underlyingList = list is IWrappedCollection wrappedCollection ? wrappedCollection.UnderlyingCollection : list; if (id != null) { diff --git a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs index aa693b03..0798b4b1 100644 --- a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs @@ -185,14 +185,12 @@ namespace Newtonsoft.Json.Utilities public static PrimitiveTypeCode GetTypeCode(Type t) { - bool isEnum; - return GetTypeCode(t, out isEnum); + return GetTypeCode(t, out _); } public static PrimitiveTypeCode GetTypeCode(Type t, out bool isEnum) { - PrimitiveTypeCode typeCode; - if (TypeCodeMap.TryGetValue(t, out typeCode)) + if (TypeCodeMap.TryGetValue(t, out PrimitiveTypeCode typeCode)) { isEnum = false; return typeCode; @@ -250,28 +248,19 @@ namespace Newtonsoft.Json.Utilities internal struct TypeConvertKey : IEquatable { - private readonly Type _initialType; - private readonly Type _targetType; + public Type InitialType { get; } - public Type InitialType - { - get { return _initialType; } - } - - public Type TargetType - { - get { return _targetType; } - } + public Type TargetType { get; } public TypeConvertKey(Type initialType, Type targetType) { - _initialType = initialType; - _targetType = targetType; + InitialType = initialType; + TargetType = targetType; } public override int GetHashCode() { - return _initialType.GetHashCode() ^ _targetType.GetHashCode(); + return InitialType.GetHashCode() ^ TargetType.GetHashCode(); } public override bool Equals(object obj) @@ -286,7 +275,7 @@ namespace Newtonsoft.Json.Utilities public bool Equals(TypeConvertKey other) { - return (_initialType == other._initialType && _targetType == other._targetType); + return (InitialType == other.InitialType && TargetType == other.TargetType); } } @@ -295,11 +284,8 @@ namespace Newtonsoft.Json.Utilities private static Func CreateCastConverter(TypeConvertKey t) { - MethodInfo castMethodInfo = t.TargetType.GetMethod("op_Implicit", new[] { t.InitialType }); - if (castMethodInfo == null) - { - castMethodInfo = t.TargetType.GetMethod("op_Explicit", new[] { t.InitialType }); - } + MethodInfo castMethodInfo = t.TargetType.GetMethod("op_Implicit", new[] { t.InitialType }) + ?? t.TargetType.GetMethod("op_Explicit", new[] { t.InitialType }); if (castMethodInfo == null) { @@ -314,48 +300,46 @@ namespace Newtonsoft.Json.Utilities #if HAVE_BIG_INTEGER internal static BigInteger ToBigInteger(object value) { - if (value is BigInteger) + if (value is BigInteger integer) { - return (BigInteger)value; + return integer; } - string s = value as string; - if (s != null) + if (value is string s) { return BigInteger.Parse(s, CultureInfo.InvariantCulture); } - if (value is float) + if (value is float f) { - return new BigInteger((float)value); + return new BigInteger(f); } - if (value is double) + if (value is double d) { - return new BigInteger((double)value); + return new BigInteger(d); } - if (value is decimal) + if (value is decimal @decimal) { - return new BigInteger((decimal)value); + return new BigInteger(@decimal); } - if (value is int) + if (value is int i) { - return new BigInteger((int)value); + return new BigInteger(i); } - if (value is long) + if (value is long l) { - return new BigInteger((long)value); + return new BigInteger(l); } - if (value is uint) + if (value is uint u) { - return new BigInteger((uint)value); + return new BigInteger(u); } - if (value is ulong) + if (value is ulong @ulong) { - return new BigInteger((ulong)value); + return new BigInteger(@ulong); } - byte[] bytes = value as byte[]; - if (bytes != null) + if (value is byte[] bytes) { return new BigInteger(bytes); } @@ -408,8 +392,7 @@ namespace Newtonsoft.Json.Utilities public static object Convert(object initialValue, CultureInfo culture, Type targetType) { - object value; - switch (TryConvertInternal(initialValue, culture, targetType, out value)) + switch (TryConvertInternal(initialValue, culture, targetType, out object value)) { case ConvertResult.Success: return value; @@ -492,21 +475,19 @@ namespace Newtonsoft.Json.Utilities } #endif - byte[] bytes = initialValue as byte[]; - if (bytes != null && targetType == typeof(Guid)) + if (initialValue is byte[] bytes && targetType == typeof(Guid)) { value = new Guid(bytes); return ConvertResult.Success; } - if (initialValue is Guid && targetType == typeof(byte[])) + if (initialValue is Guid guid && targetType == typeof(byte[])) { - value = ((Guid)initialValue).ToByteArray(); + value = guid.ToByteArray(); return ConvertResult.Success; } - string s = initialValue as string; - if (s != null) + if (initialValue is string s) { if (targetType == typeof(Guid)) { @@ -530,8 +511,7 @@ namespace Newtonsoft.Json.Utilities } if (targetType == typeof(Version)) { - Version result; - if (VersionTryParse(s, out result)) + if (VersionTryParse(s, out Version result)) { value = result; return ConvertResult.Success; @@ -552,9 +532,9 @@ namespace Newtonsoft.Json.Utilities value = ToBigInteger(initialValue); return ConvertResult.Success; } - if (initialValue is BigInteger) + if (initialValue is BigInteger integer) { - value = FromBigInteger((BigInteger)initialValue, targetType); + value = FromBigInteger(integer, targetType); return ConvertResult.Success; } #endif @@ -618,8 +598,6 @@ namespace Newtonsoft.Json.Utilities /// public static object ConvertOrCast(object initialValue, CultureInfo culture, Type targetType) { - object convertedValue; - if (targetType == typeof(object)) { return initialValue; @@ -630,7 +608,7 @@ namespace Newtonsoft.Json.Utilities return null; } - if (TryConvert(initialValue, culture, targetType, out convertedValue)) + if (TryConvert(initialValue, culture, targetType, out object convertedValue)) { return convertedValue; }