[英]Protobuf-net KeyedCollection serialization
I need to serialize/deserialize a KeyedCollection with protobuf.net, can I just serialize a list?我需要使用 protobuf.net 序列化/反序列化 KeyedCollection,我可以只序列化一个列表吗?
If so, what is the most efficient way to convert-back the List to the KeyedCollection?如果是这样,将 List 转换回 KeyedCollection 的最有效方法是什么?
Here follows a sample code that shows the case:以下是显示案例的示例代码:
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; }
}
.NET Platform Extensions 6 has an implementation of the KeyedCollection, KeyedByTypeCollection Class . .NET 平台扩展 6具有 KeyedCollection 的实现, KeyedByTypeCollection Class 。 This has a constructor which accepts an IEnumerable.
这有一个接受 IEnumerable 的构造函数。 The downside to this implementation is that the keys are the items , and it doesn't appear to allow you to change that.
此实现的缺点是键是 items ,并且它似乎不允许您更改它。 If you're already inheriting KeyedCollection, you may as well follow the implementation here and go by Microsoft's lead;
如果你已经继承了 KeyedCollection,你也可以按照这里的实现和微软的 go 来做; they just iterate and call
Add()
.他们只是迭代并调用
Add()
。
I'm also trying to tackle this issue from a Linq query perspective, possibly related posts:我也试图从 Linq 查询的角度解决这个问题,可能是相关的帖子:
The core issue seems to be that KeyedCollectedion does not contain a constructor that takes any form of ICollection to initialize its data with.核心问题似乎是KeyedCollectedion不包含采用任何形式的 ICollection 来初始化其数据的构造函数。 The base class of KeyedCollection, Collection , does however.
然而,KeyedCollection Collection的基数 class 确实如此。 The only option seems to be writing your own constructor for your KeyedCollection class that iterates over a collection and adds each element to the current instance.
唯一的选择似乎是为 KeyedCollection class 编写自己的构造函数,它遍历集合并将每个元素添加到当前实例。
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
}
This seems really inefficient though, so I hope someone corrects me...虽然这看起来效率很低,所以我希望有人纠正我......
Edit: John Franco wrote a blogpost wherein they hack together a solution for genericly casting a List with covariants (in 2009.) This doesn't look like a very good way to do things.编辑:John Franco 写了一篇博文,其中他们拼凑了一个解决方案,用于通用地转换带有协变量的列表(2009 年)。这看起来不是一个很好的做事方式。
Looking at System.Linq.Enumerable's implementation of ToList, Linq also iterates and Adds to the new collection.查看System.Linq.Enumerable对ToList的实现,Linq也迭代并添加到新的集合中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.