使用填充对象填充列表而不重复条目

本文关键字:填充 对象 列表 | 更新日期: 2023-09-27 18:27:16

我有一个应用程序,它将对象列表序列化为 json,然后通过套接字连接将其发送到客户端。

在客户端,我使用 JsonConvert.PopulateObject(( 用新收到的 json 数据填充现有的对象列表。 但是,如果存在任何重复项,则对象会不断追加到列表中,而不是重用列表中的现有对象。

这是我正在序列化/反序列化的类:

public class Process : INotifyPropertyChanged
{
    private int _id;
    private string _name;
    public int ID
    {
        get { return _id; }
        set
        {
            if (value != _id)
            {
                _id = value;
                NotifyPropertyChanged("ID");
            }
        }
    }
    public string Name
    {
        get { return _name; }
        set
        {
            if (value != _name)
            {
                _name = value;
                NotifyPropertyChanged("Name");
            }
        }
    }
    public Process() { }
    public Process(int id, string name)
    {
        ID = id;
        Name = name;
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

这是我正在使用的填充对象代码:

JsonSerializerSettings settings = new JsonSerializerSettings() { PreserveReferencesHandling = PreserveReferencesHandling.Objects, ObjectCreationHandling = ObjectCreationHandling.Auto };
ObservableCollection<Process> Processes = new ObservableCollection<Process>();
JsonConvert.PopulateObject(response, Processes, settings);

尽管属性值完全相同,但似乎 json.net 只是不知道对象是重复的引用。 我已经在我的类上尝试了 JsonObject 属性的多种组合(IsReference = true,Id = "ID"(等。 如果两个对象的 ID 属性匹配,我似乎无法让 json 识别它们是否相同。

使用填充对象填充列表而不重复条目

这不是

PreserveReferencesHandling所做的。 它用于避免序列化重复对象,从而有效地缩短 json 结果。 例:

List<NameValuePair> nvpList = new List<NameValuePair>();
NameValuePair z = new NameValuePair(Name="Ziggy", Value= 42);
nvpList.Add(z);
nvpList.Add(new NameValuePair("Zoey", 3));
nvpList.Add(z);
JsonSerializerSettings settings = new JsonSerializerSettings() { 
                PreserveReferencesHandling = PreserveReferencesHandling.Objects, 
                };
string json = JsonConvert.SerializeObject(nvpList, Formatting.Indented,
               settings);

我的List有 2 个 Ziggy 对象,但生成的 json 是:

[
  {
    "$id": "1",
    "Name": "Ziggy",
    "Value": 42
  },
  {
    "$id": "2",
    "Name": "Zoey",
    "Value": 3
  },
  {
    "$ref": "1"
  }
]

它分配一个内部$Id,然后为重复对象引用该。 这仅适用于对象引用相同的情况。 如果创建并添加了 2 个 Ziggy 对象 - 即使具有相同的值 - json 也会反映并复制它们。

为了防止反序列化时列表中出现重复项,您必须使用映射器或等效代码:

List<NameValuePair> tmp = JsonConvert.DeserializeObject<List<NameValuePair>>(json);
foreach (NameValuePair nvp in tmp)
{
    if (nvpList.Where(w => w.Value == nvp.Value).FirstOrDefault() == null)
    {
        nvpList.Add(nvp);
    }
}

这将仅添加主列表中尚不存在值/ID 的那些,添加检测重复所需的任何逻辑。

请参见: 保留对象引用

您是否尝试覆盖丝状对象的 Equals(( 函数

public override bool Equals(Process p)
{
    // If parameter is null return false:
    if ((object)p == null)
    {
        return false;
    }
    // Return true if the fields match:
    return (ID == p.ID);
}