diff --git a/Src/Newtonsoft.Json.Silverlight/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json.Silverlight/Newtonsoft.Json.Silverlight.csproj
index f407d9df..3f45c100 100644
--- a/Src/Newtonsoft.Json.Silverlight/Newtonsoft.Json.Silverlight.csproj
+++ b/Src/Newtonsoft.Json.Silverlight/Newtonsoft.Json.Silverlight.csproj
@@ -148,6 +148,9 @@
Linq\JToken.cs
+
+ Linq\JTokenEqualityComparer.cs
+
Linq\JValue.cs
diff --git a/Src/Newtonsoft.Json.Tests.Silverlight/Newtonsoft.Json.Tests.Silverlight.csproj b/Src/Newtonsoft.Json.Tests.Silverlight/Newtonsoft.Json.Tests.Silverlight.csproj
index 2bbef64b..14e1bf35 100644
--- a/Src/Newtonsoft.Json.Tests.Silverlight/Newtonsoft.Json.Tests.Silverlight.csproj
+++ b/Src/Newtonsoft.Json.Tests.Silverlight/Newtonsoft.Json.Tests.Silverlight.csproj
@@ -90,6 +90,15 @@
JsonTokenWriterTest.cs
+
+ Linq\JArrayTests.cs
+
+
+ Linq\JObjectTests.cs
+
+
+ Linq\JTokenEqualityComparerTests.cs
+
Linq\JTokenTests.cs
diff --git a/Src/Newtonsoft.Json.Tests/JavaScriptConvertTest.cs b/Src/Newtonsoft.Json.Tests/JavaScriptConvertTest.cs
index a6098906..c55af74b 100644
--- a/Src/Newtonsoft.Json.Tests/JavaScriptConvertTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JavaScriptConvertTest.cs
@@ -113,5 +113,65 @@ now brown cow?", '"', true);
string json = JavaScriptConvert.ToString(StringComparison.CurrentCultureIgnoreCase);
Assert.AreEqual("1", json);
}
+
+ [Test]
+ public void ObjectToString()
+ {
+ object value;
+
+ value = 1;
+ Assert.AreEqual("1", JavaScriptConvert.ToString(value));
+
+ value = 1.1;
+ Assert.AreEqual("1.1", JavaScriptConvert.ToString(value));
+
+ value = 1.1m;
+ Assert.AreEqual("1.1", JavaScriptConvert.ToString(value));
+
+ value = (float)1.1;
+ Assert.AreEqual("1.1", JavaScriptConvert.ToString(value));
+
+ value = (short)1;
+ Assert.AreEqual("1", JavaScriptConvert.ToString(value));
+
+ value = (long)1;
+ Assert.AreEqual("1", JavaScriptConvert.ToString(value));
+
+ value = (byte)1;
+ Assert.AreEqual("1", JavaScriptConvert.ToString(value));
+
+ value = (uint)1;
+ Assert.AreEqual("1", JavaScriptConvert.ToString(value));
+
+ value = (ushort)1;
+ Assert.AreEqual("1", JavaScriptConvert.ToString(value));
+
+ value = (sbyte)1;
+ Assert.AreEqual("1", JavaScriptConvert.ToString(value));
+
+ value = (ulong)1;
+ Assert.AreEqual("1", JavaScriptConvert.ToString(value));
+
+ value = new DateTime(JavaScriptConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
+ Assert.AreEqual(@"""\/Date(0)\/""", JavaScriptConvert.ToString(value));
+
+ value = new DateTimeOffset(JavaScriptConvert.InitialJavaScriptDateTicks, TimeSpan.Zero);
+ Assert.AreEqual(@"""\/Date(0+0000)\/""", JavaScriptConvert.ToString(value));
+
+ value = null;
+ Assert.AreEqual("null", JavaScriptConvert.ToString(value));
+
+ value = DBNull.Value;
+ Assert.AreEqual("null", JavaScriptConvert.ToString(value));
+
+ value = "I am a string";
+ Assert.AreEqual(@"""I am a string""", JavaScriptConvert.ToString(value));
+
+ value = true;
+ Assert.AreEqual("true", JavaScriptConvert.ToString(value));
+
+ value = 'c';
+ Assert.AreEqual(@"""c""", JavaScriptConvert.ToString(value));
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs
new file mode 100644
index 00000000..ec88fcee
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs
@@ -0,0 +1,294 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+ public class JArrayTests : TestFixtureBase
+ {
+ [Test]
+ public void Clear()
+ {
+ JArray a = new JArray { 1 };
+ Assert.AreEqual(1, a.Count);
+
+ a.Clear();
+ Assert.AreEqual(0, a.Count);
+ }
+
+ [Test]
+ public void Contains()
+ {
+ JValue v = new JValue(1);
+
+ JArray a = new JArray { v };
+
+ Assert.AreEqual(false, a.Contains(new JValue(2)));
+ Assert.AreEqual(false, a.Contains(new JValue(1)));
+ Assert.AreEqual(false, a.Contains(null));
+ Assert.AreEqual(true, a.Contains(v));
+ }
+
+ [Test]
+ public void GenericCollectionCopyTo()
+ {
+ JArray j = new JArray();
+ j.Add(new JValue(1));
+ j.Add(new JValue(2));
+ j.Add(new JValue(3));
+ Assert.AreEqual(3, j.Count);
+
+ JToken[] a = new JToken[5];
+
+ ((ICollection)j).CopyTo(a, 1);
+
+ Assert.AreEqual(null, a[0]);
+
+ Assert.AreEqual(1, (int)a[1]);
+
+ Assert.AreEqual(2, (int)a[2]);
+
+ Assert.AreEqual(3, (int)a[3]);
+
+ Assert.AreEqual(null, a[4]);
+
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null.
+Parameter name: array")]
+ public void GenericCollectionCopyToNullArrayShouldThrow()
+ {
+ JArray j = new JArray();
+ ((ICollection)j).CopyTo(null, 0);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"arrayIndex is less than 0.
+Parameter name: arrayIndex")]
+ public void GenericCollectionCopyToNegativeArrayIndexShouldThrow()
+ {
+ JArray j = new JArray();
+ ((ICollection)j).CopyTo(new JToken[1], -1);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"arrayIndex is equal to or greater than the length of array.")]
+ public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow()
+ {
+ JArray j = new JArray();
+ ((ICollection)j).CopyTo(new JToken[1], 1);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.")]
+ public void GenericCollectionCopyToInsufficientArrayCapacity()
+ {
+ JArray j = new JArray();
+ j.Add(new JValue(1));
+ j.Add(new JValue(2));
+ j.Add(new JValue(3));
+
+ ((ICollection)j).CopyTo(new JToken[3], 1);
+ }
+
+ [Test]
+ public void Remove()
+ {
+ JValue v = new JValue(1);
+ JArray j = new JArray();
+ j.Add(v);
+
+ Assert.AreEqual(1, j.Count);
+
+ Assert.AreEqual(false, j.Remove(new JValue(1)));
+ Assert.AreEqual(false, j.Remove(null));
+ Assert.AreEqual(true, j.Remove(v));
+ Assert.AreEqual(false, j.Remove(v));
+
+ Assert.AreEqual(0, j.Count);
+ }
+
+ [Test]
+ public void IndexOf()
+ {
+ JValue v1 = new JValue(1);
+ JValue v2 = new JValue(1);
+ JValue v3 = new JValue(1);
+
+ JArray j = new JArray();
+
+ j.Add(v1);
+ Assert.AreEqual(0, j.IndexOf(v1));
+
+ j.Add(v2);
+ Assert.AreEqual(0, j.IndexOf(v1));
+ Assert.AreEqual(1, j.IndexOf(v2));
+
+ j.AddFirst(v3);
+ Assert.AreEqual(1, j.IndexOf(v1));
+ Assert.AreEqual(2, j.IndexOf(v2));
+ Assert.AreEqual(0, j.IndexOf(v3));
+
+ v3.Remove();
+ Assert.AreEqual(0, j.IndexOf(v1));
+ Assert.AreEqual(1, j.IndexOf(v2));
+ Assert.AreEqual(-1, j.IndexOf(v3));
+ }
+
+ [Test]
+ public void RemoveAt()
+ {
+ JValue v1 = new JValue(1);
+ JValue v2 = new JValue(1);
+ JValue v3 = new JValue(1);
+
+ JArray j = new JArray();
+
+ j.Add(v1);
+ j.Add(v2);
+ j.Add(v3);
+
+ Assert.AreEqual(true, j.Contains(v1));
+ j.RemoveAt(0);
+ Assert.AreEqual(false, j.Contains(v1));
+
+ Assert.AreEqual(true, j.Contains(v3));
+ j.RemoveAt(1);
+ Assert.AreEqual(false, j.Contains(v3));
+
+ Assert.AreEqual(1, j.Count);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"index is equal to or greater than Count.
+Parameter name: index")]
+ public void RemoveAtOutOfRangeIndexShouldError()
+ {
+ JArray j = new JArray();
+ j.RemoveAt(0);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"index is less than 0.
+Parameter name: index")]
+ public void RemoveAtNegativeIndexShouldError()
+ {
+ JArray j = new JArray();
+ j.RemoveAt(-1);
+ }
+
+ [Test]
+ public void Insert()
+ {
+ JValue v1 = new JValue(1);
+ JValue v2 = new JValue(2);
+ JValue v3 = new JValue(3);
+ JValue v4 = new JValue(4);
+
+ JArray j = new JArray();
+
+ j.Add(v1);
+ j.Add(v2);
+ j.Add(v3);
+ j.Insert(1, v4);
+
+ Assert.AreEqual(0, j.IndexOf(v1));
+ Assert.AreEqual(1, j.IndexOf(v4));
+ Assert.AreEqual(2, j.IndexOf(v2));
+ Assert.AreEqual(3, j.IndexOf(v3));
+ }
+
+ [Test]
+ public void AddFirstAddedTokenShouldBeFirst()
+ {
+ JValue v1 = new JValue(1);
+ JValue v2 = new JValue(2);
+ JValue v3 = new JValue(3);
+
+ JArray j = new JArray();
+ Assert.AreEqual(null, j.First);
+ Assert.AreEqual(null, j.Last);
+
+ j.AddFirst(v1);
+ Assert.AreEqual(v1, j.First);
+ Assert.AreEqual(v1, j.Last);
+
+ j.AddFirst(v2);
+ Assert.AreEqual(v2, j.First);
+ Assert.AreEqual(v1, j.Last);
+
+ j.AddFirst(v3);
+ Assert.AreEqual(v3, j.First);
+ Assert.AreEqual(v1, j.Last);
+ }
+
+ [Test]
+ public void InsertShouldInsertAtZeroIndex()
+ {
+ JValue v1 = new JValue(1);
+ JValue v2 = new JValue(2);
+
+ JArray j = new JArray();
+
+ j.Insert(0, v1);
+ Assert.AreEqual(0, j.IndexOf(v1));
+
+ j.Insert(0, v2);
+ Assert.AreEqual(1, j.IndexOf(v1));
+ Assert.AreEqual(0, j.IndexOf(v2));
+ }
+
+ [Test]
+ public void InsertNull()
+ {
+ JArray j = new JArray();
+ j.Insert(0, null);
+
+ Assert.AreEqual(null, ((JValue)j[0]).Value);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Specified argument was out of the range of valid values.
+Parameter name: index")]
+ public void InsertNegativeIndexShouldThrow()
+ {
+ JArray j = new JArray();
+ j.Insert(-1, new JValue(1));
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Specified argument was out of the range of valid values.
+Parameter name: index")]
+ public void InsertOutOfRangeIndexShouldThrow()
+ {
+ JArray j = new JArray();
+ j.Insert(2, new JValue(1));
+ }
+
+ [Test]
+ public void Item()
+ {
+ JValue v1 = new JValue(1);
+ JValue v2 = new JValue(2);
+ JValue v3 = new JValue(3);
+ JValue v4 = new JValue(4);
+
+ JArray j = new JArray();
+
+ j.Add(v1);
+ j.Add(v2);
+ j.Add(v3);
+
+ j[1] = v4;
+
+ Assert.AreEqual(null, v2.Parent);
+ Assert.AreEqual(-1, j.IndexOf(v2));
+ Assert.AreEqual(j, v4.Parent);
+ Assert.AreEqual(1, j.IndexOf(v4));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
new file mode 100644
index 00000000..33d5fce0
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
@@ -0,0 +1,233 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+ public class JObjectTests : TestFixtureBase
+ {
+ [Test]
+ public void TryGetValue()
+ {
+ JObject o = new JObject();
+ o.Add("PropertyNameValue", new JValue(1));
+ Assert.AreEqual(1, o.Children().Count());
+
+ JToken t;
+ Assert.AreEqual(false, o.TryGetValue("sdf", out t));
+ Assert.AreEqual(null, t);
+
+ Assert.AreEqual(false, o.TryGetValue(null, out t));
+ Assert.AreEqual(null, t);
+
+ Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
+ Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t));
+ }
+
+ [Test]
+ public void DictionaryItemShouldSet()
+ {
+ JObject o = new JObject();
+ o["PropertyNameValue"] = new JValue(1);
+ Assert.AreEqual(1, o.Children().Count());
+
+ JToken t;
+ Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
+ Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t));
+
+ o["PropertyNameValue"] = new JValue(2);
+ Assert.AreEqual(1, o.Children().Count());
+
+ Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
+ Assert.AreEqual(true, JToken.DeepEquals(new JValue(2), t));
+
+ o["PropertyNameValue"] = null;
+ Assert.AreEqual(1, o.Children().Count());
+
+ Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
+ Assert.AreEqual(true, JToken.DeepEquals(new JValue((object)null), t));
+ }
+
+ [Test]
+ public void Remove()
+ {
+ JObject o = new JObject();
+ o.Add("PropertyNameValue", new JValue(1));
+ Assert.AreEqual(1, o.Children().Count());
+
+ Assert.AreEqual(false, o.Remove("sdf"));
+ Assert.AreEqual(false, o.Remove(null));
+ Assert.AreEqual(true, o.Remove("PropertyNameValue"));
+
+ Assert.AreEqual(0, o.Children().Count());
+ }
+
+ [Test]
+ public void GenericCollectionRemove()
+ {
+ JValue v = new JValue(1);
+ JObject o = new JObject();
+ o.Add("PropertyNameValue", v);
+ Assert.AreEqual(1, o.Children().Count());
+
+ Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue1", new JValue(1))));
+ Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", new JValue(2))));
+ Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", new JValue(1))));
+ Assert.AreEqual(true, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", v)));
+
+ Assert.AreEqual(0, o.Children().Count());
+ }
+
+ [Test]
+ [ExpectedException(typeof(Exception), ExpectedMessage = "Can not add property PropertyNameValue to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
+ public void DuplicatePropertyNameShouldThrow()
+ {
+ JObject o = new JObject();
+ o.Add("PropertyNameValue", null);
+ o.Add("PropertyNameValue", null);
+ }
+
+ [Test]
+ public void GenericDictionaryAdd()
+ {
+ JObject o = new JObject();
+
+ o.Add("PropertyNameValue", new JValue(1));
+ Assert.AreEqual(1, (int)o["PropertyNameValue"]);
+
+ o.Add("PropertyNameValue1", null);
+ Assert.AreEqual(null, ((JValue)o["PropertyNameValue1"]).Value);
+
+ Assert.AreEqual(2, o.Children().Count());
+ }
+
+ [Test]
+ public void GenericCollectionAdd()
+ {
+ JObject o = new JObject();
+ ((ICollection>)o).Add(new KeyValuePair("PropertyNameValue", new JValue(1)));
+
+ Assert.AreEqual(1, (int)o["PropertyNameValue"]);
+ Assert.AreEqual(1, o.Children().Count());
+ }
+
+ [Test]
+ public void GenericCollectionClear()
+ {
+ JObject o = new JObject();
+ o.Add("PropertyNameValue", new JValue(1));
+ Assert.AreEqual(1, o.Children().Count());
+
+ JProperty p = (JProperty)o.Children().ElementAt(0);
+
+ ((ICollection>)o).Clear();
+ Assert.AreEqual(0, o.Children().Count());
+
+ Assert.AreEqual(null, p.Parent);
+ }
+
+ [Test]
+ public void GenericCollectionContains()
+ {
+ JValue v = new JValue(1);
+ JObject o = new JObject();
+ o.Add("PropertyNameValue", v);
+ Assert.AreEqual(1, o.Children().Count());
+
+ bool contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", new JValue(1)));
+ Assert.AreEqual(false, contains);
+
+ contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", v));
+ Assert.AreEqual(true, contains);
+
+ contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", new JValue(2)));
+ Assert.AreEqual(false, contains);
+
+ contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue1", new JValue(1)));
+ Assert.AreEqual(false, contains);
+
+ contains = ((ICollection>)o).Contains(default(KeyValuePair));
+ Assert.AreEqual(false, contains);
+ }
+
+ [Test]
+ public void GenericDictionaryContains()
+ {
+ JObject o = new JObject();
+ o.Add("PropertyNameValue", new JValue(1));
+ Assert.AreEqual(1, o.Children().Count());
+
+ bool contains = ((IDictionary)o).ContainsKey("PropertyNameValue");
+ Assert.AreEqual(true, contains);
+ }
+
+ [Test]
+ public void GenericCollectionCopyTo()
+ {
+ JObject o = new JObject();
+ o.Add("PropertyNameValue", new JValue(1));
+ o.Add("PropertyNameValue2", new JValue(2));
+ o.Add("PropertyNameValue3", new JValue(3));
+ Assert.AreEqual(3, o.Children().Count());
+
+ KeyValuePair[] a = new KeyValuePair[5];
+
+ ((ICollection>)o).CopyTo(a, 1);
+
+ Assert.AreEqual(default(KeyValuePair), a[0]);
+
+ Assert.AreEqual("PropertyNameValue", a[1].Key);
+ Assert.AreEqual(1, (int)a[1].Value);
+
+ Assert.AreEqual("PropertyNameValue2", a[2].Key);
+ Assert.AreEqual(2, (int)a[2].Value);
+
+ Assert.AreEqual("PropertyNameValue3", a[3].Key);
+ Assert.AreEqual(3, (int)a[3].Value);
+
+ Assert.AreEqual(default(KeyValuePair), a[4]);
+
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null.
+Parameter name: array")]
+ public void GenericCollectionCopyToNullArrayShouldThrow()
+ {
+ JObject o = new JObject();
+ ((ICollection>)o).CopyTo(null, 0);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"arrayIndex is less than 0.
+Parameter name: arrayIndex")]
+ public void GenericCollectionCopyToNegativeArrayIndexShouldThrow()
+ {
+ JObject o = new JObject();
+ ((ICollection>)o).CopyTo(new KeyValuePair[1], -1);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"arrayIndex is equal to or greater than the length of array.")]
+ public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow()
+ {
+ JObject o = new JObject();
+ ((ICollection>)o).CopyTo(new KeyValuePair[1], 1);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.")]
+ public void GenericCollectionCopyToInsufficientArrayCapacity()
+ {
+ JObject o = new JObject();
+ o.Add("PropertyNameValue", new JValue(1));
+ o.Add("PropertyNameValue2", new JValue(2));
+ o.Add("PropertyNameValue3", new JValue(3));
+
+ ((ICollection>)o).CopyTo(new KeyValuePair[3], 1);
+ }
+ }
+}
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs
new file mode 100644
index 00000000..c37bd2f0
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+ public class JTokenEqualityComparerTests : TestFixtureBase
+ {
+ [Test]
+ public void JValueDictionary()
+ {
+ Dictionary dic = new Dictionary(JToken.EqualityComparer);
+ JValue v11 = new JValue(1);
+ JValue v12 = new JValue(1);
+
+ dic[v11] = 1;
+ dic[v12] += 1;
+ Assert.AreEqual(2, dic[v11]);
+ }
+
+ [Test]
+ public void JArrayDictionary()
+ {
+ Dictionary dic = new Dictionary(JToken.EqualityComparer);
+ JArray v11 = new JArray();
+ JArray v12 = new JArray();
+
+ dic[v11] = 1;
+ dic[v12] += 1;
+ Assert.AreEqual(2, dic[v11]);
+ }
+
+ [Test]
+ public void JObjectDictionary()
+ {
+ Dictionary dic = new Dictionary(JToken.EqualityComparer);
+ JObject v11 = new JObject() { { "Test", new JValue(1) }, { "Test1", new JValue(1) } };
+ JObject v12 = new JObject() { { "Test", new JValue(1) }, { "Test1", new JValue(1) } };
+
+ dic[v11] = 1;
+ dic[v12] += 1;
+ Assert.AreEqual(2, dic[v11]);
+ }
+
+ [Test]
+ public void JConstructorDictionary()
+ {
+ Dictionary dic = new Dictionary(JToken.EqualityComparer);
+ JConstructor v11 = new JConstructor("ConstructorValue");
+ JConstructor v12 = new JConstructor("ConstructorValue");
+
+ dic[v11] = 1;
+ dic[v12] += 1;
+ Assert.AreEqual(2, dic[v11]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
index 03d1454f..fee72e56 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
@@ -419,7 +419,7 @@ namespace Newtonsoft.Json.Tests.Linq
}
[Test]
- [ExpectedException(typeof(Exception), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JProperty to Newtonsoft.Json.Linq.JArray")]
+ [ExpectedException(typeof(Exception), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JProperty to Newtonsoft.Json.Linq.JArray.")]
public void AddPropertyToArray()
{
JArray a = new JArray();
@@ -427,7 +427,7 @@ namespace Newtonsoft.Json.Tests.Linq
}
[Test]
- [ExpectedException(typeof(Exception), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject")]
+ [ExpectedException(typeof(Exception), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
public void AddValueToObject()
{
JObject o = new JObject();
diff --git a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
index d74dbe23..365dfb54 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
@@ -536,7 +536,7 @@ keyword such as type of business.""
[ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Accessed JConstructor values with invalid key value: ""purple"". Argument position index expected.")]
public void JConstructorStringIndex()
{
- JConstructor c = new JConstructor();
+ JConstructor c = new JConstructor("ConstructorValue");
Assert.AreEqual(null, c["purple"]);
}
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index 29f702be..6bb6f03f 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -78,6 +78,9 @@
+
+
+
diff --git a/Src/Newtonsoft.Json/JavaScriptConvert.cs b/Src/Newtonsoft.Json/JavaScriptConvert.cs
index ec7d34fc..6c54dd0f 100644
--- a/Src/Newtonsoft.Json/JavaScriptConvert.cs
+++ b/Src/Newtonsoft.Json/JavaScriptConvert.cs
@@ -341,49 +341,88 @@ namespace Newtonsoft.Json
switch (convertible.GetTypeCode())
{
case TypeCode.String:
- return ToString((string)convertible);
+ return ToString(convertible.ToString(CultureInfo.InvariantCulture));
case TypeCode.Char:
- return ToString((char)convertible);
+ return ToString(convertible.ToChar(CultureInfo.InvariantCulture));
case TypeCode.Boolean:
- return ToString((bool)convertible);
+ return ToString(convertible.ToBoolean(CultureInfo.InvariantCulture));
case TypeCode.SByte:
- return ToString((sbyte)convertible);
+ return ToString(convertible.ToSByte(CultureInfo.InvariantCulture));
case TypeCode.Int16:
- return ToString((short)convertible);
+ return ToString(convertible.ToInt16(CultureInfo.InvariantCulture));
case TypeCode.UInt16:
- return ToString((ushort)convertible);
+ return ToString(convertible.ToUInt16(CultureInfo.InvariantCulture));
case TypeCode.Int32:
- return ToString((int)convertible);
+ return ToString(convertible.ToInt32(CultureInfo.InvariantCulture));
case TypeCode.Byte:
- return ToString((byte)convertible);
+ return ToString(convertible.ToByte(CultureInfo.InvariantCulture));
case TypeCode.UInt32:
- return ToString((uint)convertible);
+ return ToString(convertible.ToUInt32(CultureInfo.InvariantCulture));
case TypeCode.Int64:
- return ToString((long)convertible);
+ return ToString(convertible.ToInt64(CultureInfo.InvariantCulture));
case TypeCode.UInt64:
- return ToString((ulong)convertible);
+ return ToString(convertible.ToUInt64(CultureInfo.InvariantCulture));
case TypeCode.Single:
- return ToString((float)convertible);
+ return ToString(convertible.ToSingle(CultureInfo.InvariantCulture));
case TypeCode.Double:
- return ToString((double)convertible);
+ return ToString(convertible.ToDouble(CultureInfo.InvariantCulture));
case TypeCode.DateTime:
- return ToString((DateTime)convertible);
+ return ToString(convertible.ToDateTime(CultureInfo.InvariantCulture));
case TypeCode.Decimal:
- return ToString((decimal)convertible);
+ return ToString(convertible.ToDecimal(CultureInfo.InvariantCulture));
+ case TypeCode.DBNull:
+ return Null;
}
}
else if (value is DateTimeOffset)
{
return ToString((DateTimeOffset)value);
}
- else if (value is Guid)
- {
- return ToString((Guid)value);
- }
throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
}
+ internal static bool IsJsonPrimitive(object value)
+ {
+ if (value == null)
+ {
+ return true;
+ }
+ else if (value is IConvertible)
+ {
+ IConvertible convertible = value as IConvertible;
+
+ switch (convertible.GetTypeCode())
+ {
+ case TypeCode.String:
+ case TypeCode.Char:
+ case TypeCode.Boolean:
+ case TypeCode.SByte:
+ case TypeCode.Int16:
+ case TypeCode.UInt16:
+ case TypeCode.Int32:
+ case TypeCode.Byte:
+ case TypeCode.UInt32:
+ case TypeCode.Int64:
+ case TypeCode.UInt64:
+ case TypeCode.Single:
+ case TypeCode.Double:
+ case TypeCode.DateTime:
+ case TypeCode.Decimal:
+ case TypeCode.DBNull:
+ return true;
+ default:
+ return false;
+ }
+ }
+ else if (value is DateTimeOffset)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
///
/// Serializes the specified object to a JSON string.
///
diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs
index 516944a2..2cfabe3f 100644
--- a/Src/Newtonsoft.Json/JsonSerializer.cs
+++ b/Src/Newtonsoft.Json/JsonSerializer.cs
@@ -645,68 +645,9 @@ namespace Newtonsoft.Json
{
converter.WriteJson(writer, value);
}
- else if (value is IConvertible)
+ else if (JavaScriptConvert.IsJsonPrimitive(value))
{
- IConvertible convertible = value as IConvertible;
-
- switch (convertible.GetTypeCode())
- {
- case TypeCode.String:
- writer.WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Char:
- writer.WriteValue(convertible.ToChar(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Boolean:
- writer.WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture));
- break;
- case TypeCode.SByte:
- writer.WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Int16:
- writer.WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture));
- break;
- case TypeCode.UInt16:
- writer.WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Int32:
- writer.WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Byte:
- writer.WriteValue(convertible.ToByte(CultureInfo.InvariantCulture));
- break;
- case TypeCode.UInt32:
- writer.WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Int64:
- writer.WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture));
- break;
- case TypeCode.UInt64:
- writer.WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Single:
- writer.WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Double:
- writer.WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture));
- break;
- case TypeCode.DateTime:
- writer.WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Decimal:
- writer.WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture));
- break;
- case TypeCode.DBNull:
- writer.WriteNull();
- break;
- default:
- SerializeObject(writer, value);
- break;
- }
- }
- else if (value is DateTimeOffset)
- {
- writer.WriteValue((DateTimeOffset)value);
+ writer.WriteValue(value);
}
else if (value is IList)
{
diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs
index 7414cd82..b727933a 100644
--- a/Src/Newtonsoft.Json/JsonWriter.cs
+++ b/Src/Newtonsoft.Json/JsonWriter.cs
@@ -736,6 +736,82 @@ namespace Newtonsoft.Json
{
AutoComplete(JsonToken.Date);
}
+
+ ///
+ /// Writes a value.
+ /// An error will raised if the value cannot be written as a single JSON token.
+ ///
+ /// The value to write.
+ public virtual void WriteValue(object value)
+ {
+ if (value == null)
+ {
+ WriteNull();
+ }
+ else if (value is IConvertible)
+ {
+ IConvertible convertible = value as IConvertible;
+
+ switch (convertible.GetTypeCode())
+ {
+ case TypeCode.String:
+ WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.Char:
+ WriteValue(convertible.ToChar(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.Boolean:
+ WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.SByte:
+ WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.Int16:
+ WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.UInt16:
+ WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.Int32:
+ WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.Byte:
+ WriteValue(convertible.ToByte(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.UInt32:
+ WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.Int64:
+ WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.UInt64:
+ WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.Single:
+ WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.Double:
+ WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.DateTime:
+ WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.Decimal:
+ WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture));
+ return;
+ case TypeCode.DBNull:
+ WriteNull();
+ return;
+ }
+ }
+ else if (value is DateTimeOffset)
+ {
+ WriteValue((DateTimeOffset)value);
+ return;
+ }
+
+ throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
+ }
#endregion
///
diff --git a/Src/Newtonsoft.Json/Linq/JArray.cs b/Src/Newtonsoft.Json/Linq/JArray.cs
index 1441a6c3..4d4e08b6 100644
--- a/Src/Newtonsoft.Json/Linq/JArray.cs
+++ b/Src/Newtonsoft.Json/Linq/JArray.cs
@@ -220,12 +220,22 @@ namespace Newtonsoft.Json.Linq
public void Insert(int index, JToken item)
{
- JToken token = GetIndex(this, index);
- AddInternal(false, token.Previous, item);
+ if (index == 0)
+ {
+ AddFirst(item);
+ }
+ else
+ {
+ JToken token = GetIndex(this, index);
+ AddInternal(false, token.Previous, item);
+ }
}
public void RemoveAt(int index)
{
+ if (index < 0)
+ throw new ArgumentOutOfRangeException("index", "index is less than 0.");
+
int currentIndex = 0;
foreach (JToken token in Children())
{
@@ -237,18 +247,20 @@ namespace Newtonsoft.Json.Linq
currentIndex++;
}
+
+ throw new ArgumentOutOfRangeException("index", "index is equal to or greater than Count.");
}
#endregion
#region ICollection Members
- void ICollection.Add(JToken item)
+ public void Add(JToken item)
{
Add((object)item);
}
- void ICollection.Clear()
+ public void Clear()
{
RemoveAll();
}
@@ -260,6 +272,15 @@ namespace Newtonsoft.Json.Linq
void ICollection.CopyTo(JToken[] array, int arrayIndex)
{
+ if (array == null)
+ throw new ArgumentNullException("array");
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0.");
+ if (arrayIndex >= array.Length)
+ throw new ArgumentException("arrayIndex is equal to or greater than the length of array.");
+ if (Count > array.Length - arrayIndex)
+ throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.");
+
int index = 0;
foreach (JToken token in Children())
{
@@ -278,7 +299,7 @@ namespace Newtonsoft.Json.Linq
get { return false; }
}
- bool ICollection.Remove(JToken item)
+ public bool Remove(JToken item)
{
if (!((ICollection)this).Contains(item))
return false;
@@ -288,5 +309,10 @@ namespace Newtonsoft.Json.Linq
}
#endregion
+
+ internal override int GetDeepHashCode()
+ {
+ return ContentsHashCode();
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JConstructor.cs b/Src/Newtonsoft.Json/Linq/JConstructor.cs
index 16836375..c381aaea 100644
--- a/Src/Newtonsoft.Json/Linq/JConstructor.cs
+++ b/Src/Newtonsoft.Json/Linq/JConstructor.cs
@@ -58,13 +58,6 @@ namespace Newtonsoft.Json.Linq
get { return JsonTokenType.Constructor; }
}
- ///
- /// Initializes a new instance of the class.
- ///
- public JConstructor()
- {
- }
-
///
/// Initializes a new instance of the class from another object.
///
@@ -102,6 +95,8 @@ namespace Newtonsoft.Json.Linq
/// The constructor name.
public JConstructor(string name)
{
+ ValidationUtils.ArgumentNotNullOrEmpty(name, "name");
+
_name = name;
}
@@ -160,5 +155,10 @@ namespace Newtonsoft.Json.Linq
return GetIndex(this, (int)key);
}
}
+
+ internal override int GetDeepHashCode()
+ {
+ return _name.GetHashCode() ^ ContentsHashCode();
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JContainer.cs b/Src/Newtonsoft.Json/Linq/JContainer.cs
index 1ba028ab..d439845b 100644
--- a/Src/Newtonsoft.Json/Linq/JContainer.cs
+++ b/Src/Newtonsoft.Json/Linq/JContainer.cs
@@ -261,7 +261,7 @@ namespace Newtonsoft.Json.Linq
if (previous != null)
previous.Next = o;
- if (isLast)
+ if (isLast || previous == null)
_content = o;
}
}
@@ -271,7 +271,7 @@ namespace Newtonsoft.Json.Linq
ValidationUtils.ArgumentNotNull(o, "o");
if (o.Type == JsonTokenType.Property)
- throw new Exception("Can not add {0} to {1}".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
+ throw new Exception("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
}
///
@@ -422,8 +422,7 @@ namespace Newtonsoft.Json.Linq
parent = parent.Parent;
break;
case JsonToken.StartConstructor:
- JConstructor constructor = new JConstructor();
- constructor.Name = r.Value.ToString();
+ JConstructor constructor = new JConstructor(r.Value.ToString());
parent.AddObjectSkipNotify(constructor);
parent = constructor;
break;
@@ -460,5 +459,15 @@ namespace Newtonsoft.Json.Linq
}
while (r.Read());
}
+
+ internal int ContentsHashCode()
+ {
+ int hashCode = 0;
+ foreach (JToken item in Children())
+ {
+ hashCode ^= item.GetDeepHashCode();
+ }
+ return hashCode;
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JObject.cs b/Src/Newtonsoft.Json/Linq/JObject.cs
index 0aa031eb..232e2e08 100644
--- a/Src/Newtonsoft.Json/Linq/JObject.cs
+++ b/Src/Newtonsoft.Json/Linq/JObject.cs
@@ -83,7 +83,12 @@ namespace Newtonsoft.Json.Linq
ValidationUtils.ArgumentNotNull(o, "o");
if (o.Type != JsonTokenType.Property)
- throw new Exception("Can not add {0} to {1}".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
+ throw new Exception("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
+
+ JProperty property = (JProperty)o;
+ bool matchingProperty = (Properties().Where(p => string.Compare(p.Name, property.Name, StringComparison.Ordinal) == 0).Count() > 0);
+ if (matchingProperty)
+ throw new Exception("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, property.Name, GetType()));
}
internal override JToken CloneNode()
@@ -319,10 +324,20 @@ namespace Newtonsoft.Json.Linq
void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex)
{
+ if (array == null)
+ throw new ArgumentNullException("array");
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0.");
+ if (arrayIndex >= array.Length)
+ throw new ArgumentException("arrayIndex is equal to or greater than the length of array.");
+ if (Count > array.Length - arrayIndex)
+ throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.");
+
int index = 0;
foreach (JProperty property in Properties())
{
array[arrayIndex + index] = new KeyValuePair(property.Name, property.Value);
+ index++;
}
}
@@ -358,5 +373,10 @@ namespace Newtonsoft.Json.Linq
}
#endregion
+
+ internal override int GetDeepHashCode()
+ {
+ return ContentsHashCode();
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JProperty.cs b/Src/Newtonsoft.Json/Linq/JProperty.cs
index 6e07d023..2a26df0c 100644
--- a/Src/Newtonsoft.Json/Linq/JProperty.cs
+++ b/Src/Newtonsoft.Json/Linq/JProperty.cs
@@ -110,7 +110,7 @@ namespace Newtonsoft.Json.Linq
/// The property value.
public JProperty(string name, object value)
{
- ValidationUtils.ArgumentNotNullOrEmpty(name, "name");
+ ValidationUtils.ArgumentNotNull(name, "name");
_name = name;
Value = CreateFromContent(value);
@@ -149,5 +149,10 @@ namespace Newtonsoft.Json.Linq
// return (JValue)value;
//}
+
+ internal override int GetDeepHashCode()
+ {
+ return _name.GetHashCode() ^ ((Value != null) ? Value.GetDeepHashCode() : 0);
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JToken.cs b/Src/Newtonsoft.Json/Linq/JToken.cs
index d1d612ad..b18d24fa 100644
--- a/Src/Newtonsoft.Json/Linq/JToken.cs
+++ b/Src/Newtonsoft.Json/Linq/JToken.cs
@@ -42,6 +42,18 @@ namespace Newtonsoft.Json.Linq
{
private JContainer _parent;
internal JToken _next;
+ private static JTokenEqualityComparer _equalityComparer;
+
+ public static JTokenEqualityComparer EqualityComparer
+ {
+ get
+ {
+ if (_equalityComparer == null)
+ _equalityComparer = new JTokenEqualityComparer();
+
+ return _equalityComparer;
+ }
+ }
///
/// Gets or sets the parent.
@@ -705,5 +717,7 @@ namespace Newtonsoft.Json.Linq
{
return Children().GetEnumerator();
}
+
+ internal abstract int GetDeepHashCode();
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs b/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
new file mode 100644
index 00000000..999ccbb7
--- /dev/null
+++ b/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Linq
+{
+ public class JTokenEqualityComparer : IEqualityComparer
+ {
+ public bool Equals(JToken x, JToken y)
+ {
+ return JToken.DeepEquals(x, y);
+ }
+
+ public int GetHashCode(JToken obj)
+ {
+ if (obj == null)
+ return 0;
+
+ return obj.GetDeepHashCode();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JValue.cs b/Src/Newtonsoft.Json/Linq/JValue.cs
index a72d7b2f..dd250d11 100644
--- a/Src/Newtonsoft.Json/Linq/JValue.cs
+++ b/Src/Newtonsoft.Json/Linq/JValue.cs
@@ -289,5 +289,12 @@ namespace Newtonsoft.Json.Linq
throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type.");
}
}
+
+ internal override int GetDeepHashCode()
+ {
+ int valueHashCode = (_value != null) ? _value.GetHashCode() : 0;
+
+ return _valueType.GetHashCode() ^ valueHashCode;
+ }
}
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JsonTokenWriter.cs b/Src/Newtonsoft.Json/Linq/JsonTokenWriter.cs
index 79c27863..8b96f2f1 100644
--- a/Src/Newtonsoft.Json/Linq/JsonTokenWriter.cs
+++ b/Src/Newtonsoft.Json/Linq/JsonTokenWriter.cs
@@ -103,7 +103,7 @@ namespace Newtonsoft.Json.Linq
{
base.WriteStartConstructor(name);
- AddParent(new JConstructor());
+ AddParent(new JConstructor(name));
}
///
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
index 9ef8ca05..3a7cdb43 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
@@ -76,6 +76,7 @@
+