我正在使用Protobuf-net.假设我有一个序列化的Gizmo对象列表,并且每个Gizmo对象都引用一个Gazoo对象.Gazoo对象可能是几个Gizmo对象引用的同一个对象.
在这种情况下,反序列化将如何工作?
我会在Gizmo对象中为同一个引用的Gazoos获得多个Gazoos副本吗?
我所期望的是Gazoo的一个副本,用于序列化数据中的所有重复项.
为了保持一致性,我们为许多对象模型使用代码生成,其中一个分支就是通过单独的生成模块为ProtocolBuffers生成.proto文件.但是,在这一点上,我很难理解如何在List<T>对象发生时实现生成.
看起来这可以通过合同:
[ProtoMember(1)]
public List<SomeType> MyList {get; set;}
Run Code Online (Sandbox Code Playgroud)
但除此之外,我不确定如何或仅仅通过创建.proto文件/使用VS自定义工具来实现这一点.有什么想法吗?
我一直在考虑优化SQL Server内会话的状态存储的方法,我遇到的几种方法是:
现在,我在会话中存储了一个对象(称为SessionObject的类)。好消息是,它是完全可序列化的。
我认为另一种优化会话存储的好方法可能是使用协议缓冲区(protobuf-net)序列化/反序列化而不是标准BinaryFormatter。我知道我可以让所有对象继承ISerializable,但是我不想创建DTO或使用序列化/反序列化逻辑使我的Domain层混乱。
将protobuf-net与会话状态SQL Server模式一起使用的任何建议都很棒!
我有一个像这样的协议缓冲区设置:
[ProtoContract]
Foo
{
[ProtoMember(1)]
Bar[] Bars;
}
Run Code Online (Sandbox Code Playgroud)
单个Bar被编码为67字节的协议缓冲区.这听起来是正确的,因为我知道Bar几乎只是一个64字节的数组,然后有3个字节的开销用于长度前缀.
但是,当我使用20 Bars的数组编码Foo时,需要1362个字节.20*67是1340,所以只有22个字节的开销用于编码数组!
为什么这会占用这么多空间?我能做些什么来减少它吗?
众所周知,Silverlight不允许私人反思。不过,我有一个带有私有设置器的公共财产,我需要能够序列化(这里没有问题)和反序列化(bummer)。
我知道世界上没有什么东西能使protobuf-net在Silverlight中写入此属性,这必须从客户端类型(或汇编,如果该属性为内部属性)中完成。
protobuf-net中是否存在针对Silverlight的方案,这使其成为可能?我可以使该类型实现一些专用的protobuf-net接口(例如,像IProtoSerializable)。
谢谢。
编辑
我可以提出这样的方案:
[ProtoMember(N, SetterMethod = "DeserializePropValue")]
public string property Prop
{
get { return m_prop; }
private set { m_prop = value; }
}
public void DeserializePropValue(ProtoValue<string> value)
{
m_prop = value.Value;
}
Run Code Online (Sandbox Code Playgroud)
ProtoValue类型是公共的,但其构造函数是内部的,因此只有protobuf-net程序集可以创建该类型的实例。当然,protobuf-net不会公开任何公共API来创建ProtoValue对象。
此方案仅可用于Silverlight平台,其他平台仅会调用私有设置程序。
你怎么看?
编辑2
我希望指出,可以肯定的是,仍然可以获取对任意PropValue <T>实例的引用,但这不是偶然的,这些是该属性的意外覆盖,我希望消除。另外,我想让设置器不公开,这样它就不会在UI中使用的各种基于反射的绑定机制中浮出水面。
编辑3
可以使PropValue <T>实例不适合存储,这意味着在方法DeserializePropValue返回之后,相应的PropValue实例将失效。这仅是滥用它的一种方法,如下所示:
[ProtoContract]
public class Abusee
{
[ProtoMember(1, SetterMethod = "DeserializePropValue")]
public string property Prop { get; private set; }
public void DeserializePropValue(ProtoValue<string> value)
{
m_prop = value.Value;
}
}
[ProtoContract]
public class Abuser
{
private …Run Code Online (Sandbox Code Playgroud) 有没有人有一个工作的例子,其中protobuf-net可以用作BinaryFormatter的替代品?这甚至可能吗?
实际上我只需要一个类似于一种消息类型的序列化器
public class A {
public B[] Bs { get;set; }
public C[] Cs { get;set; }
}
Run Code Online (Sandbox Code Playgroud)
所有类型都在不同的程序集中定义,并具有许多属性.对于A类和其他使用的类型(B,C),是否有选项可以自动生成包含所有公共属性的proto契约,所以类似于
var formatter = ProtoBuf.Serializer.CreateFormatter<A>()
Run Code Online (Sandbox Code Playgroud)
好吗?
C#允许为枚举分配任何整数值.
当我尝试使用enum字段序列化(通过protobuf-net)对象时,该值超出范围,它会抛出异常:没有将wire-value映射到枚举PersonLevel.
我的枚举PersonLevel没有Flags属性.
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public enum PersonLevel
{
Unknown = 1
}
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class Person
{
...
public PersonLevel PersonLevel { get; set; }
...
}
Run Code Online (Sandbox Code Playgroud)
var ms = new MemoryStream();
var person = new Person
{
...
PersonLevel = (PersonLevel) 500
...
};
Serializer.Serialize(ms, person); //No wire-value is mapped to the enum PersonLevel
Run Code Online (Sandbox Code Playgroud)
是否有任何设施可以在不改变业务对象的情况下(也许是任何protobuf attrubutes)?
'No parameterless constructor found for [type]'在过去的几个小时里,我一直在努力解决这个问题.现在我创建了一个简单的单元测试,它应该反映我在应用程序中得到的内容,而且当我不这样做时,似乎抛出了这个异常stream.Position = 0.
此外,在任何情况下,当对象只是一个标准类(不是从抽象类派生)时,我都不会得到这个异常.
请参阅以下代码:
按原样运行 - 它会破坏说没有为Base找到构造函数
取消注释stream.Position = 0,它会没事的
再次注释该行,将Derived类更改为不从Base继承并取消注释类中的唯一属性,运行它 - 它不会中断(但显然Name将为null)
有人可以解释为什么这样工作吗?为什么#1抛出(或为什么#3没有)以及为什么这条消息?
[Test]
public void CanSerialize_Derived()
{
var derived = new Derived() {Name = "ngf"};
var stream = new MemoryStream();
Serializer.Serialize(stream, derived);
//stream.Position = 0;
var deserializedInstance = Serializer.Deserialize<Derived>(stream);
}
[ProtoContract]
[ProtoInclude(9, typeof(Derived))]
public abstract class Base
{
[ProtoMember(1)]
public string Name { get; set; }
}
[ProtoContract]
public class Derived : Base
{
//[ProtoMember(1)]
//public string Name { …Run Code Online (Sandbox Code Playgroud) "没有线值映射到enum foo位置16"
这个错误信息是什么意思?
i.)什么是线值?
ii.)相对的位置是什么?
在我的特殊情况下,我有:
附加信息:没有wire-value映射到位置16的枚举System.Drawing.ContentAlignment.0
在我知道的整数0的枚举中没有表示.我想只要知道错误报告的含义就会让我更好地了解如何解决这个问题.
我正在尝试使用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
}
Run Code Online (Sandbox Code Playgroud)
我正在使用,List<object>因为我在我的代码中存储了其他类的不同类实例.
但我收到此错误消息:
Unable to resolve a suitable Add method for System.Collections.Generic.Dictionary...
Run Code Online (Sandbox Code Playgroud)
这显然是因为字典,但我找不到解决方案如何解决这个问题.