-Added EqualityComparer to JsonSerializer

This commit is contained in:
James Newton-King
2015-06-14 13:40:06 +12:00
parent 70521eea88
commit 3cc797c240
8 changed files with 133 additions and 4 deletions
@@ -24,7 +24,9 @@
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
#if NETFX_CORE
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
@@ -268,6 +270,80 @@ namespace Newtonsoft.Json.Tests.Serialization
Assert.AreEqual(@"{""child"":{""name"":""child""},""name"":""parent""}", c);
}
#endif
[Test]
public void EqualityComparer()
{
AccountWithEquals account = new AccountWithEquals
{
Name = "main"
};
AccountWithEquals manager = new AccountWithEquals
{
Name = "main"
};
account.Manager = manager;
ExceptionAssert.Throws<JsonSerializationException>(
() => JsonConvert.SerializeObject(account),
"Self referencing loop detected for property 'Manager' with type 'Newtonsoft.Json.Tests.Serialization.AccountWithEquals'. Path ''.");
string json = JsonConvert.SerializeObject(account, new JsonSerializerSettings
{
EqualityComparer = new ReferenceEqualsEqualityComparer(),
Formatting = Formatting.Indented
});
StringAssert.AreEqual(@"{
""Name"": ""main"",
""Manager"": {
""Name"": ""main"",
""Manager"": null
}
}", json);
}
}
public class ReferenceEqualsEqualityComparer : IEqualityComparer
{
bool IEqualityComparer.Equals(object x, object y)
{
return ReferenceEquals(x, y);
}
int IEqualityComparer.GetHashCode(object obj)
{
#if !(NETFX_CORE)
// put objects in a bucket based on their reference
return RuntimeHelpers.GetHashCode(obj);
#else
// put all objects in the same bucket so ReferenceEquals is called on all
return -1;
#endif
}
}
public class AccountWithEquals
{
public string Name { get; set; }
public AccountWithEquals Manager { get; set; }
public override bool Equals(object obj)
{
AccountWithEquals a = obj as AccountWithEquals;
if (a == null)
return false;
return Name == a.Name;
}
public override int GetHashCode()
{
if (Name == null)
return 0;
return Name.GetHashCode();
}
}
public class PropertyItemReferenceLoopHandling