gpt4 book ai didi

c# - Protobuf-net:如何序列化复杂的集合?

转载 作者:行者123 更新时间:2023-11-30 14:49:13 30 4
gpt4 key购买 nike

我正在尝试使用 protobuf-net 序列化此类对象:

[ProtoContract]
public class RedisDataObject
{
[ProtoMember(1)]
public string DataHash;
[ProtoMember(2, DynamicType = true)]
public Dictionary<ContextActions, List<Tuple<string, List<object>>>> Value;
}

[Serializable]
public enum ContextActions
{
Insert,
Update,
Delete
}

我正在使用 List<object>因为我在代码中存储了其他类的不同类实例。

但我收到此错误消息:

Unable to resolve a suitable Add method for System.Collections.Generic.Dictionary...

这显然是因为字典,但我找不到如何解决这个问题的解决方案。

最佳答案

你的基本问题是 DynamicType = true仅适用于该特定属性,并仅为该特定属性的值序列化类型信息。它不会递归地应用于该对象包含的任何属性。但是,您的 object值嵌套在容器的多个级别中:

public Dictionary<ContextActions, List<Tuple<string, List<object>>>> Value;

你需要做的是将每个object的类型信息序列化在这个列表元组字典中。您可以通过引入替代值类型来做到这一点:

[ProtoContract]
public struct DynamicTypeSurrogate<T>
{
[ProtoMember(1, DynamicType = true)]
public T Value { get; set; }
}

public static class DynamicTypeSurrogateExtensions
{
public static List<DynamicTypeSurrogate<T>> ToSurrogateList<T>(this IList<T> list)
{
if (list == null)
return null;
return list.Select(i => new DynamicTypeSurrogate<T> { Value = i }).ToList();
}

public static List<T> FromSurrogateList<T>(this IList<DynamicTypeSurrogate<T>> list)
{
if (list == null)
return null;
return list.Select(i => i.Value).ToList();
}
}

然后修改你的RedisDataObject序列化代理字典如下:

[ProtoContract]
public class RedisDataObject
{
[ProtoMember(1)]
public string DataHash;

[ProtoIgnore]
public Dictionary<ContextActions, List<Tuple<string, List<object>>>> Value;

[ProtoMember(2)]
private Dictionary<ContextActions, List<Tuple<string, List<DynamicTypeSurrogate<object>>>>> SurrogateValue
{
get
{
if (Value == null)
return null;
var dictionary = Value.ToDictionary(
p => p.Key,
p => (p.Value == null ? null : p.Value.Select(i => Tuple.Create(i.Item1, i.Item2.ToSurrogateList())).ToList()));
return dictionary;
}
set
{
if (value == null)
Value = null;
else
{
Value = value.ToDictionary(
p => p.Key,
p => (p.Value == null ? null : p.Value.Select(i => Tuple.Create(i.Item1, i.Item2.FromSurrogateList())).ToList()));
}
}
}
}

另请注意 DynamicType 的限制提到here :

DynamicType - stores additional Type information with the type (by default it includes the AssemblyQualifiedName, although this can be controlled by the user). This makes it possible to serialize weak models, i.e. where object is used for property members, however currently this is limited to contract types (not primitives), and does not work for types with inheritance (these limitations may be removed at a later time). Like with AsReference, this uses a very different layout format

虽然上面的文档存在于 former project site并没有被移动到 current site , 从 2.0.0.668 版本开始,对非合约类型的限制肯定仍然存在。 (我测试在int上加一个List<object>值失败,我没有检查是否还有继承限制。)

关于c# - Protobuf-net:如何序列化复杂的集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39208449/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com