JValue
                    public class JValue : JToken, IEquatable<JValue>, IFormattable, IComparable, IComparable<JValue>, IConvertible
                
                Represents a value in JSON (string, integer, date, etc).
            
                using Newtonsoft.Json.Utilities;
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Newtonsoft.Json.Linq
{
    public class JValue : JToken, IEquatable<JValue>, IFormattable, IComparable, IComparable<JValue>, IConvertible
    {
        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 obj = _value?.GetType();
                Type type = value?.GetType();
                if ((object)obj != type)
                    _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;
            if ((jValue = (node as JValue)) == null)
                return false;
            if (jValue == this)
                return true;
            return ValuesEquals(this, jValue);
        }
        internal static int Compare(JTokenType valueType, object objA, object objB)
        {
            if (objA == objB)
                return 0;
            if (objB == null)
                return 1;
            if (objA != null) {
                decimal num;
                switch (valueType) {
                case JTokenType.Integer:
                    if (objA is ulong || objB is ulong || objA is decimal || objB is decimal) {
                        num = Convert.ToDecimal(objA, CultureInfo.InvariantCulture);
                        return num.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 ulong || objB is ulong || objA is decimal || objB is decimal) {
                        num = Convert.ToDecimal(objA, CultureInfo.InvariantCulture);
                        return num.CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture));
                    }
                    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: {
                    bool num2 = objA is DateTime;
                    DateTime dateTime = num2 ? ((DateTime)objA) : default(DateTime);
                    if (num2) {
                        bool num3 = objB is DateTimeOffset;
                        DateTimeOffset dateTimeOffset = num3 ? ((DateTimeOffset)objB) : default(DateTimeOffset);
                        DateTime value2 = (!num3) ? Convert.ToDateTime(objB, CultureInfo.InvariantCulture) : dateTimeOffset.DateTime;
                        return dateTime.CompareTo(value2);
                    }
                    DateTimeOffset dateTimeOffset2 = (DateTimeOffset)objA;
                    bool num4 = objB is DateTimeOffset;
                    DateTimeOffset other = num4 ? ((DateTimeOffset)objB) : default(DateTimeOffset);
                    if (!num4)
                        other = new DateTimeOffset(Convert.ToDateTime(objB, CultureInfo.InvariantCulture));
                    return dateTimeOffset2.CompareTo(other);
                }
                case JTokenType.Bytes: {
                    byte[] a;
                    if ((a = (objB as byte[])) == null)
                        throw new ArgumentException("Object must be of type byte[].");
                    return MiscellaneousUtils.ByteArrayCompare(objA as byte[], a);
                }
                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: {
                    Uri uri = objB as Uri;
                    if (uri == (Uri)null)
                        throw new ArgumentException("Object must be of type Uri.");
                    Uri uri2 = (Uri)objA;
                    return Comparer<string>.Default.Compare(uri2.ToString(), uri.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);
        }
        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 == DBNull.Value)
                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 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 valueOrDefault = current.GetValueOrDefault();
            if (valueOrDefault == JTokenType.Comment || valueOrDefault == JTokenType.String || valueOrDefault == JTokenType.Raw)
                return current.GetValueOrDefault();
            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?.ToString());
                break;
            case JTokenType.Raw:
                writer.WriteRawValue(_value?.ToString());
                break;
            case JTokenType.Null:
                writer.WriteNull();
                break;
            case JTokenType.Undefined:
                writer.WriteUndefined();
                break;
            case JTokenType.Integer: {
                object value = _value;
                bool num = value is int;
                int value2 = num ? ((int)value) : 0;
                if (num)
                    writer.WriteValue(value2);
                else {
                    value = _value;
                    bool num2 = value is long;
                    long value3 = num2 ? ((long)value) : 0;
                    if (num2)
                        writer.WriteValue(value3);
                    else {
                        value = _value;
                        bool num3 = value is ulong;
                        ulong value4 = num3 ? ((ulong)value) : 0;
                        if (num3)
                            writer.WriteValue(value4);
                        else
                            writer.WriteValue(Convert.ToInt64(_value, CultureInfo.InvariantCulture));
                    }
                }
                break;
            }
            case JTokenType.Float: {
                object value = _value;
                bool num5 = value is decimal;
                decimal value6 = num5 ? ((decimal)value) : default(decimal);
                if (num5)
                    writer.WriteValue(value6);
                else {
                    value = _value;
                    bool num6 = value is double;
                    double value7 = num6 ? ((double)value) : 0;
                    if (num6)
                        writer.WriteValue(value7);
                    else {
                        value = _value;
                        bool num7 = value is float;
                        float value8 = num7 ? ((float)value) : 0;
                        if (num7)
                            writer.WriteValue(value8);
                        else
                            writer.WriteValue(Convert.ToDouble(_value, CultureInfo.InvariantCulture));
                    }
                }
                break;
            }
            case JTokenType.String:
                writer.WriteValue(_value?.ToString());
                break;
            case JTokenType.Boolean:
                writer.WriteValue(Convert.ToBoolean(_value, CultureInfo.InvariantCulture));
                break;
            case JTokenType.Date: {
                object value = _value;
                bool num4 = value is DateTimeOffset;
                DateTimeOffset value5 = num4 ? ((DateTimeOffset)value) : default(DateTimeOffset);
                if (num4)
                    writer.WriteValue(value5);
                else
                    writer.WriteValue(Convert.ToDateTime(_value, CultureInfo.InvariantCulture));
                break;
            }
            case JTokenType.Bytes:
                writer.WriteValue((byte[])_value);
                break;
            case JTokenType.Guid:
                writer.WriteValue((_value != null) ? ((Guid?)_value) : null);
                break;
            case JTokenType.TimeSpan:
                writer.WriteValue((_value != null) ? ((TimeSpan?)_value) : null);
                break;
            case JTokenType.Uri:
                writer.WriteValue((Uri)_value);
                break;
            default:
                throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", _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)
        {
            return Equals(obj as JValue);
        }
        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;
            if ((formattable = (_value as IFormattable)) != null)
                return formattable.ToString(format, formatProvider);
            return _value.ToString();
        }
        int IComparable.CompareTo(object obj)
        {
            if (obj == null)
                return 1;
            JValue jValue = obj as JValue;
            object objB;
            JTokenType valueType;
            if (jValue != null) {
                objB = jValue.Value;
                valueType = ((_valueType == JTokenType.String && _valueType != jValue._valueType) ? jValue._valueType : _valueType);
            } else {
                objB = obj;
                valueType = _valueType;
            }
            return Compare(valueType, _value, objB);
        }
        public int CompareTo(JValue obj)
        {
            if (obj == null)
                return 1;
            return Compare((_valueType == JTokenType.String && _valueType != obj._valueType) ? obj._valueType : _valueType, _value, obj._value);
        }
        TypeCode IConvertible.GetTypeCode()
        {
            if (_value == null)
                return TypeCode.Empty;
            IConvertible convertible;
            if ((convertible = (_value as IConvertible)) != null)
                return convertible.GetTypeCode();
            return TypeCode.Object;
        }
        bool IConvertible.ToBoolean(IFormatProvider provider)
        {
            return (bool)(JToken)this;
        }
        char IConvertible.ToChar(IFormatProvider provider)
        {
            return (char)(JToken)this;
        }
        sbyte IConvertible.ToSByte(IFormatProvider provider)
        {
            return (sbyte)(JToken)this;
        }
        byte IConvertible.ToByte(IFormatProvider provider)
        {
            return (byte)(JToken)this;
        }
        short IConvertible.ToInt16(IFormatProvider provider)
        {
            return (short)(JToken)this;
        }
        ushort IConvertible.ToUInt16(IFormatProvider provider)
        {
            return (ushort)(JToken)this;
        }
        int IConvertible.ToInt32(IFormatProvider provider)
        {
            return (int)(JToken)this;
        }
        uint IConvertible.ToUInt32(IFormatProvider provider)
        {
            return (uint)(JToken)this;
        }
        long IConvertible.ToInt64(IFormatProvider provider)
        {
            return (long)(JToken)this;
        }
        ulong IConvertible.ToUInt64(IFormatProvider provider)
        {
            return (ulong)(JToken)this;
        }
        float IConvertible.ToSingle(IFormatProvider provider)
        {
            return (float)(JToken)this;
        }
        double IConvertible.ToDouble(IFormatProvider provider)
        {
            return (double)(JToken)this;
        }
        decimal IConvertible.ToDecimal(IFormatProvider provider)
        {
            return (decimal)(JToken)this;
        }
        DateTime IConvertible.ToDateTime(IFormatProvider provider)
        {
            return (DateTime)(JToken)this;
        }
        object IConvertible.ToType(Type conversionType, IFormatProvider provider)
        {
            return ToObject(conversionType);
        }
    }
}