简体   繁体   English

Protobuf.net KeyedCollection 序列化

[英]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; }
}

Solution?解决方案?

.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()

See also也可以看看

Previous thoughts以前的想法

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM