C# JsonSerializer调用容器等于重写方法

C# JsonSerializer调用容器等于重写方法,c#,json,serialization,polymorphism,overriding,C#,Json,Serialization,Polymorphism,Overriding,首先,我仔细查看了一下,了解了override/virtual等,但没有发现任何特定于我的情况的案例,我相信这不是唯一的。我只想确保我使用的实现是正确的实现。我有以下代码设置来演示我的问题: using System; using System.Collections.Generic; using System.IO; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace Sa

首先,我仔细查看了一下,了解了override/virtual等,但没有发现任何特定于我的情况的案例,我相信这不是唯一的。我只想确保我使用的实现是正确的实现。我有以下代码设置来演示我的问题:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Sandpit
{
    public class Program
    {
        static void Main()
        {
            var fixture = new Fixture
                {
                    Name = "Fixture Name",
                    Participants = new List<Participant> {new Participant {Name = "Participant Name"}}
                };

            var writer = new StringWriter(new StringBuilder());
            var serializer = new JsonSerializer();
            serializer.Converters.Add(new StringEnumConverter());
            serializer.Serialize(writer, fixture);

            Console.Write(writer.ToString());
            Console.ReadKey();
        }
    }

    public class Fixture
    {
        public string Name { get; set; }
        public List<Participant> Participants { get; set; }

        public override bool Equals(object obj)
        {
            var fixture = (Fixture)obj;

            return fixture.Name == Name;
        }

        public override int GetHashCode()
        {
            return Name.GetHashCode();
        }
    }

    public class Participant
    {
        public string Name { get; set; }

        public override bool Equals(object obj)
        {
            var participant = (Participant)obj;

            return participant.Name == Name;
        }

        public override int GetHashCode()
        {
            return Name.GetHashCode();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用系统文本;
使用Newtonsoft.Json;
使用Newtonsoft.Json.Converters;
名称空间沙坑
{
公共课程
{
静态void Main()
{
var夹具=新夹具
{
Name=“Fixture Name”,
参与者=新列表{new Participant{Name=“Participant Name”}
};
var writer=new StringWriter(new StringBuilder());
var serializer=new JsonSerializer();
添加(新的StringEnumConverter());
序列化器。序列化(编写器、夹具);
Console.Write(writer.ToString());
Console.ReadKey();
}
}
公务舱固定装置
{
公共字符串名称{get;set;}
公共列表参与者{get;set;}
公共覆盖布尔等于(对象对象对象)
{
var fixture=(fixture)obj;
返回fixture.Name==Name;
}
公共覆盖int GetHashCode()
{
返回Name.GetHashCode();
}
}
公开课参与者
{
公共字符串名称{get;set;}
公共覆盖布尔等于(对象对象对象)
{
var参与者=(参与者)obj;
返回参与者。名称==名称;
}
公共覆盖int GetHashCode()
{
返回Name.GetHashCode();
}
}
}
现在当这个运行时,我在
var fixture=(fixture)obj上得到一个异常

无法强制转换类型为的对象 要键入的'System.Collections.Generic.List'1[Sandpit.Participant]' “沙坑固定装置”

我不明白为什么它会进入那里。以及为什么这会破坏重写的
对象
方法的正确实现

我知道我可以通过执行
public new bool Equals(object obj)
来解决这个问题。我这样做对吗?此外,这些对象已很好地集成到我正在处理的应用程序中,进行此更改可能会有任何副作用吗

非常感谢,,
Matt

对您的
固定装置和
参与者
课程进行一个小改动,可以解决以下问题:

public class Fixture 
{
    public string Name { get; set; }
    public List<Participant> Participants { get; set; }

    public override bool Equals(object obj)
    {
        var fixture = obj as Fixture;
        return fixture == null ? false : fixture.Name == Name;
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }
}

public class Participant 
{
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        var participant = obj as Participant;
        return participant == null ? false : participant.Name == Name;
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }
}
公共类设备
{
公共字符串名称{get;set;}
公共列表参与者{get;set;}
公共覆盖布尔等于(对象对象对象)
{
var夹具=obj作为夹具;
返回fixture==null?false:fixture.Name==Name;
}
公共覆盖int GetHashCode()
{
返回Name.GetHashCode();
}
}
公开课参与者
{
公共字符串名称{get;set;}
公共覆盖布尔等于(对象对象对象)
{
var参与者=作为参与者的obj;
返回参与者==null?false:participant.Name==Name;
}
公共覆盖int GetHashCode()
{
返回Name.GetHashCode();
}
}

如果要与另一种类型的元素进行比较,可以确定两者不相等

对您的
装置
参与者
课程进行一个小改动,可以解决以下问题:

public class Fixture 
{
    public string Name { get; set; }
    public List<Participant> Participants { get; set; }

    public override bool Equals(object obj)
    {
        var fixture = obj as Fixture;
        return fixture == null ? false : fixture.Name == Name;
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }
}

public class Participant 
{
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        var participant = obj as Participant;
        return participant == null ? false : participant.Name == Name;
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }
}
公共类设备
{
公共字符串名称{get;set;}
公共列表参与者{get;set;}
公共覆盖布尔等于(对象对象对象)
{
var夹具=obj作为夹具;
返回fixture==null?false:fixture.Name==Name;
}
公共覆盖int GetHashCode()
{
返回Name.GetHashCode();
}
}
公开课参与者
{
公共字符串名称{get;set;}
公共覆盖布尔等于(对象对象对象)
{
var参与者=作为参与者的obj;
返回参与者==null?false:participant.Name==Name;
}
公共覆盖int GetHashCode()
{
返回Name.GetHashCode();
}
}

如果要与另一种类型的元素进行比较,可以确定两者不相等

另一种选择是使用“obj作为夹具/参与者”,然后检查是否为空。另一种选择是使用“obj作为夹具/参与者”,然后检查是否为空。似乎有效。我决定将public bool Equals方法的内容放在覆盖中的null检查之后。如果这听起来没问题,你能更新你的答案吗?在我看来,问题是一个不同类型的对象被发送到Equals方法中。至少可以说,为什么有人会在Equals方法中发送不同类型的对象有点奇怪,但在任何情况下都要检查这一点是令人头痛的。Equals方法不应使用其他对象类型调用。@Ted覆盖了==和!=等运算符还要求您重载Equals。当你知道对象不同时,调用Equals当然是胡说八道。但是Equals(or==,!=)的目的是当你不知道的时候。因此,使用不同的对象调用它是完全有意义的,因为您在编译时并不了解所有内容。还可以看看使用泛型Equals的IEquatable(),我决定将public bool Equals方法的内容放在覆盖中的null检查之后。如果这听起来没问题,你能更新你的答案吗?在我看来,问题是一个不同类型的对象被发送到Equals方法中。至少可以说,为什么有人会在Equals方法中发送不同类型的对象有点奇怪,但在任何情况下都要检查这一点是令人头痛的。Equals方法不应使用其他对象类型调用。@Ted覆盖了==和!=等运算符还要求您重载Equals。当你知道对象不同时,调用Equals当然是胡说八道