1

我需要用 protobuf-net 序列化/反序列化 KeyedCollection,我可以只序列化一个列表吗?

如果是这样,将列表转换回 KeyedCollection 的最有效方法是什么?

下面是一个显示案例的示例代码:

public class FamilySurrogate
{
    public List<Person> PersonList { get; set; }

    public FamilySurrogate(List<Person> personList)
    {
        PersonList = personList;
    }


    public static implicit operator Family(FamilySurrogate surrogate)
    {
        if (surrogate == null) return null;

        var people = new PersonKeyedCollection();
        foreach (var person in surrogate.PersonList)  // Is there a most efficient way?
            people.Add(person);

        return new Family(people);

    }

    public static implicit operator FamilySurrogate(Family source)
    {
        return source == null ? null : new FamilySurrogate(source.People.ToList());
    }

}

public class Person
{
    public Person(string name, string surname)
    {
        Name = name;
        Surname = surname;
    }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Fullname { get { return $"{Name} {Surname}"; } }
}

public class PersonKeyedCollection : System.Collections.ObjectModel.KeyedCollection<string, Person>
{        
    protected override string GetKeyForItem(Person item) { return item.Fullname; }
}

public class Family
{
    public Family(PersonKeyedCollection people)
    {
        People = people;
    }

    public PersonKeyedCollection People { get; set; }
}
4

1 回答 1

1

解决方案?

.NET 平台扩展 6具有 KeyedCollection、KeyedByTypeCollection 类的实现。这有一个接受 IEnumerable的构造函数。此实现的缺点是键是 items,它似乎不允许您更改它。如果你已经继承了 KeyedCollection,你也可以按照这里的实现,跟随微软的步伐;他们只是迭代并调用Add().

也可以看看

以前的想法

我也试图从 Linq 查询的角度来解决这个问题,可能是相关的帖子:

核心问题似乎是KeyedCollectedion不包含采用任何形式的 ICollection 来初始化其数据的构造函数。然而,KeyedCollection 的基类Collection确实如此。唯一的选择似乎是为您的 KeyedCollection 类编写自己的构造函数,该类遍历集合并将每个元素添加到当前实例。

using System.Collections.Generic;
using System.Collections.ObjectModel;

public class VariableList<T> : KeyedCollection<string, T>
{
    // KeyedCollection does not seem to support explicitly casting from an IEnumerable,
    // so we're creating a constructor who's sole purpose is to build a new KeyedCollection.
    public VariableList(IEnumerable<T> items)
    {
        foreach (T item in items)
            Add(item);
    }

    // insert other code here
}

不过这似乎效率很低,所以我希望有人纠正我......

编辑:John Franco 写了一篇文,他们在其中破解了一个解决方案,用于通用地投射带有协变的列表(在 2009 年!)这看起来不是一个很好的做事方式。

查看 System.Linq.Enumerable 的ToList实现,Linq 还迭代并添加到新集合中。

于 2022-02-09T02:04:37.077 回答