// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; #if FEATURE_DYNAMIC using System.Dynamic; #endif using System.Globalization; using System.IO; using System.Linq.Expressions; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Text; using System.Xml; namespace System.Json { /// /// This is the base class for JavaScript Object Notation (JSON) common language runtime (CLR) types. /// [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "JsonValue is by definition either a collection or a single object.")] [DataContract] #if FEATURE_DYNAMIC public class JsonValue : IEnumerable>, IDynamicMetaObjectProvider #else public class JsonValue : IEnumerable> #endif { private static JsonValue defaultInstance = new JsonValue(); private int changingListenersCount; private int changedListenersCount; internal JsonValue() { } /// /// Raised when this or any of its members have changed. /// ///

Events are raised when elements are added or removed to /// instances. It applies to both complex descendants of : /// and .

///

You should be careful when modifying a tree within one of these events, /// because doing this might lead to unexpected results. For example, if you receive a Changing event, and while /// the event is being processed you remove the node from the tree, you might not receive the Changed event. When /// an event is being processed, it is valid to modify a tree other than the one that contains the node that is /// receiving the event; it is even valid to modify the same tree provided the modifications do not affect the /// specific nodes on which the event was raised. However, if you modify the area of the tree that contains the /// node receiving the event, the events that you receive and the impact to the tree are undefined.

public event EventHandler Changed { add { changedListenersCount++; OnChanged += value; } remove { changedListenersCount--; OnChanged -= value; } } /// /// Raised when this or any of its members are about to be changed. /// ///

Events are raised when elements are added or removed to /// instances. It applies to both complex descendants of : /// and .

///

You should be careful when modifying a tree within one of these events, /// because doing this might lead to unexpected results. For example, if you receive a Changing event, and while /// the event is being processed you remove the node from the tree, you might not receive the Changed event. When /// an event is being processed, it is valid to modify a tree other than the one that contains the node that is /// receiving the event; it is even valid to modify the same tree provided the modifications do not affect the /// specific nodes on which the event was raised. However, if you modify the area of the tree that contains the /// node receiving the event, the events that you receive and the impact to the tree are undefined.

public event EventHandler Changing { add { changingListenersCount++; OnChanging += value; } remove { changingListenersCount--; OnChanging -= value; } } private event EventHandler OnChanged; private event EventHandler OnChanging; /// /// Gets the JSON CLR type represented by this instance. /// public virtual JsonType JsonType { get { return JsonType.Default; } } /// /// Gets the number of items in this object. /// public virtual int Count { get { return 0; } } /// /// Gets the number of listeners to the event for this instance. /// protected int ChangingListenersCount { get { return changingListenersCount; } } /// /// Gets the number of listeners to the event for this instance. /// protected int ChangedListenersCount { get { return changedListenersCount; } } /// /// Gets the default JsonValue instance. /// This instance enables safe-chaining of JsonValue operations and resolves to 'null' /// when this instance is used as dynamic, mapping to the JavaScript 'null' value. /// private static JsonValue DefaultInstance { get { return defaultInstance; } } /// /// This indexer is not supported for this base class and throws an exception. /// /// The key of the element to get or set. /// . /// The exception thrown is the . /// This method is overloaded in the implementation of the /// class, which inherits from this class. public virtual JsonValue this[string key] { get { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(string), JsonType)); } set { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(string), JsonType)); } } /// /// This indexer is not supported for this base class and throws an exception. /// /// The zero-based index of the element to get or set. /// . /// The exception thrown is the . /// This method is overloaded in the implementation of the /// class, which inherits from this class. public virtual JsonValue this[int index] { get { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(int), JsonType)); } set { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(int), JsonType)); } } /// /// Deserializes text-based JSON into a JSON CLR type. /// /// The text-based JSON to be parsed into a JSON CLR type. /// The object that represents the parsed /// text-based JSON as a CLR type. /// The length of jsonString is zero. /// jsonString is null. /// The result will be an instance of either , /// or , /// depending on the text-based JSON supplied to the method. public static JsonValue Parse(string json) { return JXmlToJsonValueConverter.JXMLToJsonValue(json); } /// /// Deserializes text-based JSON from a text reader into a JSON CLR type. /// /// A over text-based JSON content. /// The object that represents the parsed /// text-based JSON as a CLR type. /// textReader is null. /// The result will be an instance of either , /// or , /// depending on the text-based JSON supplied to the method. public static JsonValue Load(TextReader textReader) { if (textReader == null) { throw new ArgumentNullException("textReader"); } return JsonValue.Parse(textReader.ReadToEnd()); } /// /// Deserializes text-based JSON from a stream into a JSON CLR type. /// /// A that contains text-based JSON content. /// The object that represents the parsed /// text-based JSON as a CLR type. /// stream is null. /// The result will be an instance of either , /// or , /// depending on the text-based JSON supplied to the method. public static JsonValue Load(Stream stream) { return JXmlToJsonValueConverter.JXMLToJsonValue(stream); } /// /// Performs a cast operation from a instance into the specified type parameter./> /// /// The type to cast the instance to. /// The instance. /// An object of type T initialized with the value specified. /// This method is to support the framework and is not intended to be used externally, use explicit type cast instead. [EditorBrowsable(EditorBrowsableState.Never)] [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "The generic parameter is used to specify the output type")] public static T CastValue(JsonValue value) { Type typeofT = typeof(T); if ((value != null && typeofT.IsAssignableFrom(value.GetType())) || typeofT == typeof(object)) { return (T)(object)value; } if (value == null || value.JsonType == JsonType.Default) { if (typeofT.IsValueType) { throw new InvalidCastException(RS.Format(Properties.Resources.InvalidCastNonNullable, typeofT.FullName)); } else { return default(T); } } try { return value.ReadAs(); } catch (Exception ex) { if (ex is FormatException || ex is NotSupportedException || ex is InvalidCastException) { throw new InvalidCastException(RS.Format(Properties.Resources.CannotCastJsonValue, value.GetType().FullName, typeofT.FullName), ex); } throw; } } /// /// Returns an enumerator which iterates through the values in this object. /// /// An enumerator which which iterates through the values in this object. /// The enumerator returned by this class is empty; subclasses will override this method to return appropriate enumerators for themselves. public IEnumerator> GetEnumerator() { return GetKeyValuePairEnumerator(); } /// /// Returns an enumerator which iterates through the values in this object. /// /// An which iterates through the values in this object. /// The enumerator returned by this class is empty; subclasses will override this method to return appropriate enumerators for themselves. IEnumerator IEnumerable.GetEnumerator() { return GetKeyValuePairEnumerator(); } #if FEATURE_DYNAMIC /// /// Gets this instance as a dynamic object. /// /// This instance as dynamic. public dynamic AsDynamic() { return this; } #endif /// /// Attempts to convert this instance into the type T. /// /// The type to which the conversion is being performed. /// An instance of T initialized with this instance, or the default value of T if the conversion cannot be performed. /// true if this instance can be read as type T; otherwise, false. public bool TryReadAs(out T valueOfT) { object value; if (TryReadAs(typeof(T), out value)) { valueOfT = (T)value; return true; } valueOfT = default(T); return false; } /// /// Attempts to convert this instance into the type T. /// /// The type to which the conversion is being performed. /// An instance of T initialized with the value from the conversion of this instance. /// If this value cannot be converted into the type T. [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "The generic parameter is used to specify the output type")] public T ReadAs() { return (T)ReadAs(typeof(T)); } /// /// Attempts to convert this instance into the type T. /// /// The type to which the conversion is being performed. /// The fallback value to be returned if the conversion cannot be made. /// An instance of T initialized with the value from the conversion of this instance, or the specified fallback value if the conversion cannot be made. public T ReadAs(T fallback) { return (T)ReadAs(typeof(T), fallback); } /// /// Attempts to convert this instance to an instance of the specified type. /// /// The type to which the conversion is being performed. /// The fallback value to be returned if the conversion cannot be made. /// An instance of the specified type initialized with the value from the conversion of this instance, or the specified fallback value if the conversion cannot be made. public object ReadAs(Type type, object fallback) { if (type == null) { throw new ArgumentNullException("type"); } object result; if (JsonType != JsonType.Default && TryReadAs(type, out result)) { return result; } else { return fallback; } } /// /// Attempts to convert this instance into an instance of the specified type. /// /// The type to which the conversion is being performed. /// An instance of the specified type initialized with the value from the conversion of this instance. /// If this value cannot be converted into the type T. public virtual object ReadAs(Type type) { if (type == null) { throw new ArgumentNullException("type"); } object result; if (TryReadAs(type, out result)) { return result; } throw new NotSupportedException(RS.Format(Properties.Resources.CannotReadAsType, GetType().FullName, type.FullName)); } /// /// Attempts to convert this instance into an instance of the specified type. /// /// The type to which the conversion is being performed. /// An object to be initialized with this instance or null if the conversion cannot be performed. /// true if this instance can be read as the specified type; otherwise, false. [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "This is the non-generic version of the method.")] public virtual bool TryReadAs(Type type, out object value) { if (type == null) { throw new ArgumentNullException("type"); } if (type.IsAssignableFrom(GetType()) || type == typeof(object)) { value = this; return true; } value = null; return false; } /// /// Writes this instance to a . /// /// Stream to which to write text-based JSON. public void Save(Stream stream) { if (JsonType == JsonType.Default) { throw new InvalidOperationException(Properties.Resources.UseOfDefaultNotAllowed); } if (stream == null) { throw new ArgumentNullException("stream"); } using (XmlDictionaryWriter jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, false)) { jsonWriter.WriteStartElement(JXmlToJsonValueConverter.RootElementName); Save(jsonWriter); jsonWriter.WriteEndElement(); } } /// /// Writes instance to a . /// /// The used to write text-based JSON. public void Save(TextWriter textWriter) { if (JsonType == JsonType.Default) { throw new InvalidOperationException(Properties.Resources.UseOfDefaultNotAllowed); } if (textWriter == null) { throw new ArgumentNullException("textWriter"); } using (MemoryStream ms = new MemoryStream()) { Save(ms); ms.Position = 0; textWriter.Write(new StreamReader(ms).ReadToEnd()); } } /// /// Provides a textual representation of this instance. /// /// A containing text-based JSON. public override string ToString() { if (JsonType == JsonType.Default) { return "Default"; } using (MemoryStream ms = new MemoryStream()) { Save(ms); ms.Position = 0; return new StreamReader(ms).ReadToEnd(); } } /// /// Checks whether a key/value pair with a specified key exists in the JSON CLR object type. /// /// The key to check for. /// false in this class; subclasses may override this method to return other values. /// This method is overloaded in the implementation of the /// class, which inherits from this class. public virtual bool ContainsKey(string key) { return false; } /// /// Returns the value returned by the safe string indexer for this instance. /// /// The key of the element to get. /// If this is an instance of , it contains /// the given key and the value corresponding to the key is not null, then it will return that value. /// Otherwise it will return a instance with /// equals to . [EditorBrowsable(EditorBrowsableState.Never)] public virtual JsonValue GetValue(string key) { return ValueOrDefault(key); } /// /// Returns the value returned by the safe int indexer for this instance. /// /// The zero-based index of the element to get. /// If this is an instance of , the index is within the array /// bounds, and the value corresponding to the index is not null, then it will return that value. /// Otherwise it will return a instance with /// equals to . [EditorBrowsable(EditorBrowsableState.Never)] public virtual JsonValue GetValue(int index) { return ValueOrDefault(index); } /// /// Sets the value and returns it. /// /// The key of the element to set. /// The value to be set. /// The value, converted into a JsonValue, set in this collection. /// If the value cannot be converted into a JsonValue. [EditorBrowsable(EditorBrowsableState.Never)] public virtual JsonValue SetValue(string key, object value) { this[key] = ResolveObject(value); return this[key]; } /// /// Sets the value and returns it. /// /// The zero-based index of the element to set. /// The value to be set. /// The value, converted into a JsonValue, set in this collection. /// If the value cannot be converted into a JsonValue. [EditorBrowsable(EditorBrowsableState.Never)] public virtual JsonValue SetValue(int index, object value) { this[index] = ResolveObject(value); return this[index]; } /// /// Safe string indexer for the type. /// /// The key of the element to get. /// If this is an instance of , it contains /// the given key and the value corresponding to the key is not null, then it will return that value. /// Otherwise it will return a instance with /// equals to . public virtual JsonValue ValueOrDefault(string key) { return JsonValue.DefaultInstance; } /// /// Safe indexer for the type. /// /// The zero-based index of the element to get. /// If this is an instance of , the index is within the array /// bounds, and the value corresponding to the index is not null, then it will return that value. /// Otherwise it will return a instance with /// equals to . public virtual JsonValue ValueOrDefault(int index) { return JsonValue.DefaultInstance; } /// /// Safe deep indexer for the type. /// /// The indices to index this type. The indices can be /// of type or . /// A which is equivalent to calling or /// on the first index, then calling it again on the result /// for the second index and so on. /// If any of the indices is not of type /// or . public JsonValue ValueOrDefault(params object[] indexes) { if (indexes == null) { return JsonValue.DefaultInstance; } if (indexes.Length == 0) { return this; } JsonValue result = this; for (int i = 0; i < indexes.Length; i++) { object index = indexes[i]; if (index == null) { result = JsonValue.DefaultInstance; continue; } Type indexType = index.GetType(); switch (Type.GetTypeCode(indexType)) { case TypeCode.Char: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Byte: case TypeCode.SByte: index = System.Convert.ChangeType(index, typeof(int), CultureInfo.InvariantCulture); goto case TypeCode.Int32; case TypeCode.Int32: result = result.ValueOrDefault((int)index); break; case TypeCode.String: result = result.ValueOrDefault((string)index); break; default: throw new ArgumentException(RS.Format(Properties.Resources.InvalidIndexType, index.GetType()), "indexes"); } } return result; } #if FEATURE_DYNAMIC [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "Cannot make this class sealed, it needs to have subclasses. But its subclasses are sealed themselves.")] DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) { if (parameter == null) { throw new ArgumentNullException("parameter"); } return new JsonValueDynamicMetaObject(parameter, this); } #endif /// /// Resolves the specified object to an appropriate JsonValue instance. /// /// The object to resolve. /// A instance resolved from the specified object. internal static JsonValue ResolveObject(object value) { JsonPrimitive primitive; if (value == null) { return null; } JsonValue jsonValue = value as JsonValue; if (jsonValue != null) { return jsonValue; } if (JsonPrimitive.TryCreate(value, out primitive)) { return primitive; } throw new ArgumentException(Properties.Resources.TypeNotSupported, "value"); } /// /// Determines whether an explicit cast to JsonValue is provided from the specified type. /// /// The type to check. /// true if an explicit cast exists for the specified type, false otherwise. internal static bool IsSupportedExplicitCastType(Type type) { TypeCode typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Boolean: case TypeCode.Byte: case TypeCode.Char: case TypeCode.DateTime: case TypeCode.Decimal: case TypeCode.Double: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.SByte: case TypeCode.Single: case TypeCode.String: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: return true; default: return type == typeof(DateTimeOffset) || type == typeof(Guid) || type == typeof(Uri) || type == typeof(List) || type == typeof(Array) || type == typeof(object[]) || type == typeof(Dictionary); } } /// /// Returns the value this object wraps (if any). /// /// The value wrapped by this instance or null if none. internal virtual object Read() { return null; } /// /// Serializes this object into the specified instance. /// /// An instance to serialize this instance into. internal virtual void Save(XmlDictionaryWriter jsonWriter) { if (jsonWriter == null) { throw new ArgumentNullException("jsonWriter"); } Stack objectStack = new Stack(); Stack indexStack = new Stack(); int currentIndex = 0; JsonValue currentValue = this; OnSaveStarted(); WriteAttributeString(jsonWriter); while (currentIndex < currentValue.Count || objectStack.Count > 0) { if (currentValue.Count > currentIndex) { JsonValue nextValue = currentValue.WriteStartElementAndGetNext(jsonWriter, currentIndex); if (JsonValue.IsJsonCollection(nextValue)) { nextValue.OnSaveStarted(); nextValue.WriteAttributeString(jsonWriter); objectStack.Push(currentValue); indexStack.Push(currentIndex); currentValue = nextValue; currentIndex = 0; } else { if (nextValue == null) { jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.NullAttributeValue); } else { nextValue.Save(jsonWriter); } currentIndex++; jsonWriter.WriteEndElement(); } } else { if (objectStack.Count > 0) { currentValue.OnSaveEnded(); jsonWriter.WriteEndElement(); currentValue = objectStack.Pop(); currentIndex = indexStack.Pop() + 1; } } } OnSaveEnded(); } /// /// Returns an enumerator which iterates through the values in this object. /// /// An which iterates through the values in this object. /// This method is the virtual version of the IEnumerator.GetEnumerator method and is provided to allow derived classes to implement the /// appropriate version of the generic interface (enumerator of values or key/value pairs). [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method is a virtual version of the IEnumerable.GetEnumerator method.")] [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This class is a collection that is properly represented by the nested generic type.")] protected virtual IEnumerator> GetKeyValuePairEnumerator() { yield break; } /// /// Callback method called during Save operations to let the instance write the start element /// and return the next element in the collection. /// /// The JXML writer used to write JSON. /// The index within this collection. /// The next item in the collection, or null of there are no more items. internal virtual JsonValue WriteStartElementAndGetNext(XmlDictionaryWriter jsonWriter, int index) { return null; } /// /// Callback method called to let an instance write the proper JXML attribute when saving this /// instance. /// /// The JXML writer used to write JSON. internal virtual void WriteAttributeString(XmlDictionaryWriter jsonWriter) { } /// /// Callback method called when a Save operation is starting for this instance. /// protected virtual void OnSaveStarted() { } /// /// Callback method called when a Save operation is finished for this instance. /// protected virtual void OnSaveEnded() { } /// /// Called internally to raise the event. /// /// The object which caused the event to be raised. /// The arguments to the event. [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "This is a helper function used to raise the event.")] [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", Justification = "This is not externally visible, since the constructor for this class is internal (cannot be directly derived) and all its subclasses are sealed.")] protected void RaiseChangingEvent(object sender, JsonValueChangeEventArgs eventArgs) { EventHandler changing = OnChanging; if (changing != null) { changing(sender, eventArgs); } } /// /// Called internally to raise the event. /// /// The object which caused the event to be raised. /// The arguments to the event. [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "This is a helper function used to raise the event.")] [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", Justification = "This is not externally visible, since the constructor for this class is internal (cannot be directly derived) and all its subclasses are sealed.")] protected void RaiseChangedEvent(object sender, JsonValueChangeEventArgs eventArgs) { EventHandler changed = OnChanged; if (changed != null) { changed(sender, eventArgs); } } private static bool IsJsonCollection(JsonValue value) { return value != null && (value.JsonType == JsonType.Array || value.JsonType == JsonType.Object); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified or null if value is null. public static explicit operator string(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator double(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator float(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator decimal(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator long(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. [CLSCompliant(false)] public static explicit operator ulong(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator int(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. [CLSCompliant(false)] public static explicit operator uint(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator short(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. [CLSCompliant(false)] public static explicit operator ushort(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. [CLSCompliant(false)] public static explicit operator sbyte(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator byte(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified or null if value is null. public static explicit operator Uri(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator Guid(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator DateTime(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator char(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator bool(JsonValue value) { return CastValue(value); } /// /// Enables explicit casts from an instance of type to a object. /// /// The instance of used to initialize the object. /// The initialized with the value specified. public static explicit operator DateTimeOffset(JsonValue value) { return CastValue(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(bool value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(byte value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(decimal value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(double value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(short value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(int value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(long value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(float value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified, or null if the value is null. [SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads", Justification = "This operator does not intend to represent a Uri overload.")] public static implicit operator JsonValue(string value) { return value == null ? null : new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(char value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(DateTime value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(Guid value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified, or null if the value is null. public static implicit operator JsonValue(Uri value) { return value == null ? null : new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. [CLSCompliant(false)] public static implicit operator JsonValue(sbyte value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. [CLSCompliant(false)] public static implicit operator JsonValue(ushort value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. [CLSCompliant(false)] public static implicit operator JsonValue(uint value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. [CLSCompliant(false)] public static implicit operator JsonValue(ulong value) { return new JsonPrimitive(value); } /// /// Enables implicit casts from type to a . /// /// The instance used to initialize the . /// The initialized with the specified. public static implicit operator JsonValue(DateTimeOffset value) { return new JsonPrimitive(value); } } }