【问题标题】:JsonConvert.SerializeObject passes custom type properties to parent types Equals(object) methodJsonConvert.SerializeObject 将自定义类型属性传递给父类型 Equals(object) 方法
【发布时间】:2014-10-24 16:20:28
【问题描述】:

我看到使用 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) 3 次,传入的不是 TestObject,而是 CustomTypePropety 对象,然后是 ListProperty,然后是 ListCustomProperty。在我的情况下,这会导致 InvalidCastException,因为 TestObject 尝试将 obj 参数转换为 TestObject。我无法在实际场景中更改此设置,因为该类型位于第三方库中。

这是 Json.NET 中的错误还是我做错了什么?我已经挖掘了一段时间,找不到任何解决方案。感谢您的帮助。

编辑

我刚刚升级到 Json.NET 6.0.6 并看到了相同的行为。

【问题讨论】:

    标签: c# serialization json.net


    【解决方案1】:

    如果您正在实现 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,那肯定是bug。我会联系作者并要求他们修复它。

    至于为什么Json.Net在对不同类型的对象进行序列化时会调用Equals,这样做是为了检查引用循环。详情请见Why does Json.Net call the Equals method on my objects when serializing?

    【讨论】:

    • 我认为您根本不应该感到愚蠢@r2_118 =) 我认为这是一种完全奇怪的行为,不应该发生。将对象传递给不同类型的 equals 方法是非常奇怪的。我现在也遇到了同样的问题,很头疼。
    • 当我在这里问为什么时得到了答案:stackoverflow.com/questions/51669072/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多