JsonConvert.SerializeObject将自定义类型属性传递给父类型Equals(对象)方法
本文关键字:类型 父类 Equals 对象 方法 SerializeObject 自定义 属性 JsonConvert | 更新日期: 2023-09-27 18:27:47
我看到一些奇怪的行为正在用Json.NET v6.0.5对覆盖Equals方法并具有引用类型属性(字符串除外)的对象进行序列化。
public class TestObject
{
public ChildObject CustomTypeProperty
{
get;
set;
}
public List<string> ListProperty
{
get;
set;
}
public List<ChildObject> ListCustomProperty
{
get;
set;
}
public string StringProperty
{
get;
set;
}
public int IntProperty
{
get;
set;
}
public override bool Equals(object obj)
{
Console.WriteLine(obj.GetType().FullName);
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
public class ChildObject
{
}
然后我把它序列化。
var testObj = new TestObject() { CustomTypeProperty = new ChildObject(), IntProperty = 1, ListCustomProperty = new List<ChildObject>(), ListProperty = new List<string>(), StringProperty = "abc" };
var json = JsonConvert.SerializeObject(testObj);
我可以看到它调用了三次TestObject.Equals(object obj),并且传入的不是TestObject,而是CustomTypeProperty对象,然后是ListProperty,然后是List CustomProperty。在我的案例中,这会导致InvalidCastException,因为TestObject试图将obj参数强制转换为TestObject。我无法在现实世界的场景中更改这一点,因为类型在第三方库中。
这是Json.NET中的错误还是我做错了什么?我已经挖了一段时间,找不到任何解决办法。谢谢你的帮助。
编辑
我刚刚升级到Json.NET 6.0.6,看到了同样的行为。
如果要实现bool Equals(object obj)
的重写,则需要处理可能传递给您的任何类型。您不能假设调用者总是传递您期望的类型。通常的解决方案是在投射之前进行简单的类型检查,如下所示:
public override bool Equals(object obj)
{
if (obj is TypeYouAreExpecting)
{
TypeYouAreExpecting other = (TypeYouAreExpecting) obj;
bool areEqual = false;
// implement your equals logic here
return areEqual;
}
return base.Equals(obj);
}
如果是第三方库在Equals
方法中抛出了InvalidCastException
,那么这肯定是一个错误。我会联系作者并要求他们修复它。
至于Json.Net为什么在对不同类型的对象进行序列化时调用Equals
,这样做是为了检查引用循环。请参阅为什么Json.Net在序列化时对我的对象调用Equals方法?了解更多详细信息。