我需要用Protobuf-net序列化/挑选一个键盘,我可以序列化列表吗?
如果是这样,什么是将列表转换为键控的最有效方法?
这里遵循一个示例代码,显示出:
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平台扩展6 具有KeyedCollection,KeyedByTyPecollection类的实现。这具有一个可以接受可恢复的构造函数。此实现的缺点是键是项目,它似乎不允许您更改它。如果您已经继承了KeyEdCollection,则不妨在此处遵循该实现,并按照Microsoft的领先优势进行;他们只是迭代并致电Add()
。
另请参见
- .net中的keyedbytypecollection使用?
- 似乎无法解析keyedByTypeCollection?
- 什么是Learn.microsoft.com上的.NET平台扩展?
- LINQ带有自定义基础集合
- 收集初始化
以前的想法
我还试图从LINQ查询角度解决此问题,可能是相关的帖子:
- 无法隐式将类型System.Collections.generic.list.list返回到linq查询之后的对象
- dotnet/runtime:为什么KeyEdCollection抽象?
核心问题似乎是KeyedCollectedion不包含采用任何形式的Icollection来初始化其数据的构造函数。但是,KeyedCollection的基类Collection确实。唯一的选项似乎是为您的键控类编写自己的构造函数,该类迭代在集合上迭代并将每个元素添加到当前实例中。
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.shumerable的实现Tolist,Linq还迭代并添加到新集合中。