<PackageReference Include="Newtonsoft.Json" Version="6.0.6" />

JValue

Represents a value in JSON (string, integer, date, etc).
using Newtonsoft.Json.Utilities; using System; using System.Collections.Generic; using System.Dynamic; using System.Globalization; using System.Linq.Expressions; using System.Numerics; namespace Newtonsoft.Json.Linq { public class JValue : JToken, IEquatable<JValue>, IFormattable, IComparable, IComparable<JValue> { private class JValueDynamicProxy : DynamicProxy<JValue> { public override bool TryConvert(JValue instance, ConvertBinder binder, out object result) { if ((object)binder.Type == typeof(JValue)) { result = instance; return true; } object value = instance.Value; if (value == null) { result = null; return ReflectionUtils.IsNullable(binder.Type); } result = ConvertUtils.Convert(value, CultureInfo.InvariantCulture, binder.Type); return true; } public override bool TryBinaryOperation(JValue instance, BinaryOperationBinder binder, object arg, out object result) { object objB = (arg is JValue) ? ((JValue)arg).Value : arg; switch (binder.Operation) { case ExpressionType.Equal: result = (Compare(instance.Type, instance.Value, objB) == 0); return true; case ExpressionType.NotEqual: result = (Compare(instance.Type, instance.Value, objB) != 0); return true; case ExpressionType.GreaterThan: result = (Compare(instance.Type, instance.Value, objB) > 0); return true; case ExpressionType.GreaterThanOrEqual: result = (Compare(instance.Type, instance.Value, objB) >= 0); return true; case ExpressionType.LessThan: result = (Compare(instance.Type, instance.Value, objB) < 0); return true; case ExpressionType.LessThanOrEqual: result = (Compare(instance.Type, instance.Value, objB) <= 0); return true; case ExpressionType.Add: case ExpressionType.Divide: case ExpressionType.Multiply: case ExpressionType.Subtract: case ExpressionType.AddAssign: case ExpressionType.DivideAssign: case ExpressionType.MultiplyAssign: case ExpressionType.SubtractAssign: if (Operation(binder.Operation, instance.Value, objB, out result)) { result = new JValue(result); return true; } break; } result = null; return false; } } private JTokenType _valueType; private object _value; public override bool HasValues => false; public override JTokenType Type => _valueType; public new object Value { get { return _value; } set { Type type = (_value != null) ? _value.GetType() : null; Type type2 = value?.GetType(); if ((object)type != type2) _valueType = GetValueType(_valueType, value); _value = value; } } internal JValue(object value, JTokenType type) { _value = value; _valueType = type; } public JValue(JValue other) : this(other.Value, other.Type) { } public JValue(long value) : this(value, JTokenType.Integer) { } public JValue(decimal value) : this(value, JTokenType.Float) { } public JValue(char value) : this(value, JTokenType.String) { } [CLSCompliant(false)] public JValue(ulong value) : this(value, JTokenType.Integer) { } public JValue(double value) : this(value, JTokenType.Float) { } public JValue(float value) : this(value, JTokenType.Float) { } public JValue(DateTime value) : this(value, JTokenType.Date) { } public JValue(DateTimeOffset value) : this(value, JTokenType.Date) { } public JValue(bool value) : this(value, JTokenType.Boolean) { } public JValue(string value) : this(value, JTokenType.String) { } public JValue(Guid value) : this(value, JTokenType.Guid) { } public JValue(Uri value) : this(value, (value != (Uri)null) ? JTokenType.Uri : JTokenType.Null) { } public JValue(TimeSpan value) : this(value, JTokenType.TimeSpan) { } public JValue(object value) : this(value, GetValueType(null, value)) { } internal override bool DeepEquals(JToken node) { JValue jValue = node as JValue; if (jValue == null) return false; if (jValue == this) return true; return ValuesEquals(this, jValue); } private static int CompareBigInteger(BigInteger i1, object i2) { int num = i1.CompareTo(ConvertUtils.ToBigInteger(i2)); if (num != 0) return num; if (i2 is decimal) { decimal num2 = (decimal)i2; return 0.CompareTo(Math.Abs(num2 - Math.Truncate(num2))); } if (i2 is double || i2 is float) { double num3 = Convert.ToDouble(i2, CultureInfo.InvariantCulture); return 0.CompareTo(Math.Abs(num3 - Math.Truncate(num3))); } return num; } internal static int Compare(JTokenType valueType, object objA, object objB) { if (objA == null && objB == null) return 0; if (objA != null && objB == null) return 1; if (objA != null || objB == null) { switch (valueType) { case JTokenType.Integer: if (objA is BigInteger) return CompareBigInteger((BigInteger)objA, objB); if (objB is BigInteger) return -CompareBigInteger((BigInteger)objB, objA); if (objA is ulong || objB is ulong || objA is decimal || objB is decimal) return Convert.ToDecimal(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture)); if (objA is float || objB is float || objA is double || objB is double) return CompareFloat(objA, objB); return Convert.ToInt64(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToInt64(objB, CultureInfo.InvariantCulture)); case JTokenType.Float: if (objA is BigInteger) return CompareBigInteger((BigInteger)objA, objB); if (objB is BigInteger) return -CompareBigInteger((BigInteger)objB, objA); return CompareFloat(objA, objB); case JTokenType.Comment: case JTokenType.String: case JTokenType.Raw: { string strA = Convert.ToString(objA, CultureInfo.InvariantCulture); string strB = Convert.ToString(objB, CultureInfo.InvariantCulture); return string.CompareOrdinal(strA, strB); } case JTokenType.Boolean: { bool flag = Convert.ToBoolean(objA, CultureInfo.InvariantCulture); bool value4 = Convert.ToBoolean(objB, CultureInfo.InvariantCulture); return flag.CompareTo(value4); } case JTokenType.Date: { if (objA is DateTime) { DateTime dateTime = (DateTime)objA; DateTime value2 = (!(objB is DateTimeOffset)) ? Convert.ToDateTime(objB, CultureInfo.InvariantCulture) : ((DateTimeOffset)objB).DateTime; return dateTime.CompareTo(value2); } DateTimeOffset dateTimeOffset = (DateTimeOffset)objA; DateTimeOffset other = (objB is DateTimeOffset) ? ((DateTimeOffset)objB) : new DateTimeOffset(Convert.ToDateTime(objB, CultureInfo.InvariantCulture)); return dateTimeOffset.CompareTo(other); } case JTokenType.Bytes: { if (!(objB is byte[])) throw new ArgumentException("Object must be of type byte[]."); byte[] array = objA as byte[]; byte[] array2 = objB as byte[]; if (array == null) return -1; if (array2 == null) return 1; return MiscellaneousUtils.ByteArrayCompare(array, array2); } case JTokenType.Guid: { if (!(objB is Guid)) throw new ArgumentException("Object must be of type Guid."); Guid guid = (Guid)objA; Guid value3 = (Guid)objB; return guid.CompareTo(value3); } case JTokenType.Uri: { if (!(objB is Uri)) throw new ArgumentException("Object must be of type Uri."); Uri uri = (Uri)objA; Uri uri2 = (Uri)objB; return Comparer<string>.Default.Compare(uri.ToString(), uri2.ToString()); } case JTokenType.TimeSpan: { if (!(objB is TimeSpan)) throw new ArgumentException("Object must be of type TimeSpan."); TimeSpan timeSpan = (TimeSpan)objA; TimeSpan value = (TimeSpan)objB; return timeSpan.CompareTo(value); } default: throw MiscellaneousUtils.CreateArgumentOutOfRangeException("valueType", valueType, "Unexpected value type: {0}".FormatWith(CultureInfo.InvariantCulture, valueType)); } } return -1; } private static int CompareFloat(object objA, object objB) { double d = Convert.ToDouble(objA, CultureInfo.InvariantCulture); double num = Convert.ToDouble(objB, CultureInfo.InvariantCulture); if (MathUtils.ApproxEquals(d, num)) return 0; return d.CompareTo(num); } private static bool Operation(ExpressionType operation, object objA, object objB, out object result) { if ((objA is string || objB is string) && (operation == ExpressionType.Add || operation == ExpressionType.AddAssign)) { result = objA?.ToString() + objB?.ToString(); return true; } if (objA is BigInteger || objB is BigInteger) { if (objA == null || objB == null) { result = null; return true; } BigInteger bigInteger = ConvertUtils.ToBigInteger(objA); BigInteger bigInteger2 = ConvertUtils.ToBigInteger(objB); switch (operation) { case ExpressionType.Add: case ExpressionType.AddAssign: result = bigInteger + bigInteger2; return true; case ExpressionType.Subtract: case ExpressionType.SubtractAssign: result = bigInteger - bigInteger2; return true; case ExpressionType.Multiply: case ExpressionType.MultiplyAssign: result = bigInteger * bigInteger2; return true; case ExpressionType.Divide: case ExpressionType.DivideAssign: result = bigInteger / bigInteger2; return true; } } else if (objA is ulong || objB is ulong || objA is decimal || objB is decimal) { if (objA == null || objB == null) { result = null; return true; } decimal d = Convert.ToDecimal(objA, CultureInfo.InvariantCulture); decimal d2 = Convert.ToDecimal(objB, CultureInfo.InvariantCulture); switch (operation) { case ExpressionType.Add: case ExpressionType.AddAssign: result = d + d2; return true; case ExpressionType.Subtract: case ExpressionType.SubtractAssign: result = d - d2; return true; case ExpressionType.Multiply: case ExpressionType.MultiplyAssign: result = d * d2; return true; case ExpressionType.Divide: case ExpressionType.DivideAssign: result = d / d2; return true; } } else if (objA is float || objB is float || objA is double || objB is double) { if (objA == null || objB == null) { result = null; return true; } double num = Convert.ToDouble(objA, CultureInfo.InvariantCulture); double num2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture); switch (operation) { case ExpressionType.Add: case ExpressionType.AddAssign: result = num + num2; return true; case ExpressionType.Subtract: case ExpressionType.SubtractAssign: result = num - num2; return true; case ExpressionType.Multiply: case ExpressionType.MultiplyAssign: result = num * num2; return true; case ExpressionType.Divide: case ExpressionType.DivideAssign: result = num / num2; return true; } } else if (objA is int || objA is uint || objA is long || objA is short || objA is ushort || objA is sbyte || objA is byte || objB is int || objB is uint || objB is long || objB is short || objB is ushort || objB is sbyte || objB is byte) { if (objA == null || objB == null) { result = null; return true; } long num3 = Convert.ToInt64(objA, CultureInfo.InvariantCulture); long num4 = Convert.ToInt64(objB, CultureInfo.InvariantCulture); switch (operation) { case ExpressionType.Add: case ExpressionType.AddAssign: result = num3 + num4; return true; case ExpressionType.Subtract: case ExpressionType.SubtractAssign: result = num3 - num4; return true; case ExpressionType.Multiply: case ExpressionType.MultiplyAssign: result = num3 * num4; return true; case ExpressionType.Divide: case ExpressionType.DivideAssign: result = num3 / num4; return true; } } result = null; return false; } internal override JToken CloneToken() { return new JValue(this); } public static JValue CreateComment(string value) { return new JValue(value, JTokenType.Comment); } public static JValue CreateString(string value) { return new JValue(value, JTokenType.String); } public static JValue CreateNull() { return new JValue(null, JTokenType.Null); } public static JValue CreateUndefined() { return new JValue(null, JTokenType.Undefined); } private static JTokenType GetValueType(JTokenType? current, object value) { if (value == null) return JTokenType.Null; if (value is string) return GetStringValueType(current); if (value is long || value is int || value is short || value is sbyte || value is ulong || value is uint || value is ushort || value is byte) return JTokenType.Integer; if (value is Enum) return JTokenType.Integer; if (value is BigInteger) return JTokenType.Integer; if (value is double || value is float || value is decimal) return JTokenType.Float; if (value is DateTime) return JTokenType.Date; if (value is DateTimeOffset) return JTokenType.Date; if (value is byte[]) return JTokenType.Bytes; if (value is bool) return JTokenType.Boolean; if (value is Guid) return JTokenType.Guid; if (value is Uri) return JTokenType.Uri; if (value is TimeSpan) return JTokenType.TimeSpan; throw new ArgumentException("Could not determine JSON object type for type {0}.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); } private static JTokenType GetStringValueType(JTokenType? current) { if (!current.HasValue) return JTokenType.String; JTokenType value = current.Value; if (value == JTokenType.Comment || value == JTokenType.String || value == JTokenType.Raw) return current.Value; return JTokenType.String; } public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) { if (converters != null && converters.Length > 0 && _value != null) { JsonConverter matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType()); if (matchingConverter != null && matchingConverter.CanWrite) { matchingConverter.WriteJson(writer, _value, JsonSerializer.CreateDefault()); return; } } switch (_valueType) { case JTokenType.Comment: writer.WriteComment((_value != null) ? _value.ToString() : null); break; case JTokenType.Raw: writer.WriteRawValue((_value != null) ? _value.ToString() : null); break; case JTokenType.Null: writer.WriteNull(); break; case JTokenType.Undefined: writer.WriteUndefined(); break; case JTokenType.Integer: if (_value is BigInteger) writer.WriteValue((BigInteger)_value); else writer.WriteValue(Convert.ToInt64(_value, CultureInfo.InvariantCulture)); break; case JTokenType.Float: if (_value is decimal) writer.WriteValue((decimal)_value); else if (_value is double) { writer.WriteValue((double)_value); } else if (_value is float) { writer.WriteValue((float)_value); } else { writer.WriteValue(Convert.ToDouble(_value, CultureInfo.InvariantCulture)); } break; case JTokenType.String: writer.WriteValue((_value != null) ? _value.ToString() : null); break; case JTokenType.Boolean: writer.WriteValue(Convert.ToBoolean(_value, CultureInfo.InvariantCulture)); break; case JTokenType.Date: if (_value is DateTimeOffset) writer.WriteValue((DateTimeOffset)_value); else writer.WriteValue(Convert.ToDateTime(_value, CultureInfo.InvariantCulture)); break; case JTokenType.Bytes: writer.WriteValue((byte[])_value); break; case JTokenType.Guid: case JTokenType.Uri: case JTokenType.TimeSpan: writer.WriteValue((_value != null) ? _value.ToString() : null); break; default: throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type."); } } internal override int GetDeepHashCode() { int num = (_value != null) ? _value.GetHashCode() : 0; int valueType = (int)_valueType; return valueType.GetHashCode() ^ num; } private static bool ValuesEquals(JValue v1, JValue v2) { if (v1 != v2) { if (v1._valueType == v2._valueType) return Compare(v1._valueType, v1._value, v2._value) == 0; return false; } return true; } public bool Equals(JValue other) { if (other == null) return false; return ValuesEquals(this, other); } public override bool Equals(object obj) { if (obj == null) return false; JValue jValue = obj as JValue; if (jValue != null) return Equals(jValue); return base.Equals(obj); } public override int GetHashCode() { if (_value == null) return 0; return _value.GetHashCode(); } public override string ToString() { if (_value == null) return string.Empty; return _value.ToString(); } public string ToString(string format) { return ToString(format, CultureInfo.CurrentCulture); } public string ToString(IFormatProvider formatProvider) { return ToString(null, formatProvider); } public string ToString(string format, IFormatProvider formatProvider) { if (_value == null) return string.Empty; IFormattable formattable = _value as IFormattable; if (formattable != null) return formattable.ToString(format, formatProvider); return _value.ToString(); } protected override DynamicMetaObject GetMetaObject(Expression parameter) { return new DynamicProxyMetaObject<JValue>(parameter, this, new JValueDynamicProxy(), true); } int IComparable.CompareTo(object obj) { if (obj == null) return 1; object objB = (obj is JValue) ? ((JValue)obj).Value : obj; return Compare(_valueType, _value, objB); } public int CompareTo(JValue obj) { if (obj == null) return 1; return Compare(_valueType, _value, obj._value); } } }