我有一个简单的信息:
包装测试;
message sendName {
可选字符串username = 1;
}
令人敬畏的VS插件生成.cs文件:
名称空间测试
[global :: System.Serializable global :: ProtoBuf.ProtoContract(Name = @"sendName")]
public partial class sendName:global :: ProtoBuf.IExtensible {
Run Code Online (Sandbox Code Playgroud)public sendName() {} private string _username = ""; [global::ProtoBuf.ProtoMember(1, IsRequired = false, Name=@"username", DataFormat = > global::ProtoBuf.DataFormat.Default)] [global::System.ComponentModel.DefaultValue("")] public string username { get { return _username; } set { _username = value; } } private global::ProtoBuf.IExtension extensionObject; global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing) { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); } } }
我正在使用java从java端发送消息
objName.build()的writeTo((FileOutputStream中)socket.getOutputStream()).
在我的C#应用程序中,它的作用类似于Socket Listener,我有一个名为Listen的方法,它监听java客户端发送的消息:
public void …
我即将开始一个项目来连接两个程序,一个在c#中,一个在c ++中.我已经有一个有效的c#程序,可以与其他版本的自己交谈.在开始使用c ++版本之前,我已经想到了一些问题:
1)我正在使用protobuf-net v1.我认为来自序列化程序的.proto文件正是c ++版本的模板所需要的?谷歌搜索提到了关于pascal外壳的一些内容,但我不知道这是否重要.
2)如果其中一种.NET类型在c ++中没有直接对应物,我该怎么办?如果我有小数或字典怎么办?我是否必须以某种方式修改.proto文件并将数据压缩成不同的形状?(我将检查文件,看看我是否可以搞清楚)
3)人们可以想到还有其他问题吗?二进制格式和类似的东西?
编辑我现在看了一个原型文件.似乎.NET特定的东西被标记为例如bcl.DateTime或bcl.Decimal.子类型包含在原型定义中.不过,我不知道如何处理bcl类型.如果我的c ++ prog看到一个小数,它会怎么做?
症状:没有为类型定义序列化程序:System.Array
由于所有C#数组都继承自Array类,我认为这在ProtoBuf-net中是有效的
[ProtoMember(1)]
public Array SomeKindOfArray = new int[]{1,2,3,4,5};
[ProtoMember(2)]
public List<Array> SomeKindOfList = new List<Array>();
Run Code Online (Sandbox Code Playgroud)
我应该使用RuntimeTypeModel注册Array吗?
m.Add(typeof (Array), true); // does not seem to help
Run Code Online (Sandbox Code Playgroud)
尝试:
new int[]{1,2,3,4} // works
(object)new int[] { 1, 2, 3, 4 } // does not work
(Array)new int[] { 1, 2, 3, 4 } // does not work
Run Code Online (Sandbox Code Playgroud)
另一种可能的解决方案(现在找不到SO url):
有一个基类型类项的列表.
包裹每种类型.例如
class TheBase{}
class ArrayOfInt { public int[] value;}
Run Code Online (Sandbox Code Playgroud)
然后,它将成为转换到包装器列表之一.有更简单的方法吗?
我正在使用Protobuf.net来序列化一些类.我希望能够序列化SuperHero类(如下),而无需在基类上指定[ProtoInclude].这是因为派生类是自动生成的,但基类不是,因此基类不直接知道它的派生类.
[ProtoContract]
class Person
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
}
[ProtoContract]
class SuperHero : Person
{
[ProtoMember(3)]
public string Powers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我使用的是最新版本的protobuf.net.
我在NuGet(2.0.0.480)上使用最新版本的ProtoBuf,它没有序列化标记为DataContract/ DataMemberattributes的类型:
[DataContract]
public class Person
{
[DataMember]
public string Firstname { get; set; }
}
class Program
{
static void Main(string[] args)
{
var outputFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "person.dat");
var person = new Person { Firstname = "ben" };
using (var fs = new FileStream(outputFile, FileMode.OpenOrCreate)) {
Serializer.Serialize(fs, person);
}
using (var fs = File.OpenRead(outputFile))
{
var result = Serializer.Deserialize<Person>(fs);
Console.WriteLine(result.Firstname);
}
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用ProtoBuf特定属性修饰我的类:
[ProtoContract]
public class Person
{
[ProtoMember(1)]
public string Firstname { get; …Run Code Online (Sandbox Code Playgroud) 灵感来自这个问题.我创建了一个小的基准程序来比较ProtoBuf,BinaryFormatter和Json.NET.基准测试本身是一个基于控制台的小型控制台,位于https://github.com/sidshetye/SerializersCompare.可以随意添加/改进,添加新的串行器非常简单.无论如何,我的结果是:
Binary Formatter ProtoBuf Json.NET ServiceStackJson ServiceStackJSV
Loop Size:512 bytes Size:99 bytes Size:205 bytes Size:205 bytes Size:181 bytes
1 16.1242 ms 151.6354 ms 277.2085 ms 129.8321 ms 146.3547 ms
2 0.0673 ms 0.0349 ms 0.0727 ms 0.0343 ms 0.0370 ms
4 0.0292 ms 0.0085 ms 0.0303 ms 0.0145 ms 0.0148 ms
8 0.0255 ms 0.0069 ms 0.0017 ms 0.0216 ms 0.0129 ms
16 0.0011 ms 0.0064 ms 0.0282 ms 0.0114 ms 0.0120 ms
32 0.0164 ms …Run Code Online (Sandbox Code Playgroud) 假设我想序列化,然后使用protobuf-net反序列化小数:
const decimal originalDecimal = 1.6641007661819458m;
using (var memoryStream = new MemoryStream())
{
Serializer.Serialize(memoryStream, originalDecimal);
memoryStream.Position = 0;
var deserializedDecimal = Serializer.Deserialize<decimal>(memoryStream);
Assert.AreEqual(originalDecimal, deserializedDecimal);
}
Run Code Online (Sandbox Code Playgroud)
它工作正常.Protobuf-net内部使用以下小数表示(参见Bcl.proto):
message Decimal {
optional uint64 lo = 1; // the first 64 bits of the underlying value
optional uint32 hi = 2; // the last 32 bis of the underlying value
optional sint32 signScale = 3; // the number of decimal digits, and the sign
}
Run Code Online (Sandbox Code Playgroud)
现在说我用代码定义了一个假定的等价原型合约:
[ProtoContract]
public class MyDecimal
{ …Run Code Online (Sandbox Code Playgroud) 今天,我一直在使用protobuf-net乱搞,遇到了一个奇怪的情况。下面的代码未按预期反序列化。最后两次反序列化尝试成功,但是它们不正确。反序列化的对象将IsEmpty设置为true实际应设置为的时间false。我已经能够使用私有设置程序获取属性以进行序列化了,但是这一行为并不正确。它与链接的默认构造函数有关吗?
class Program2
{
static void Main(string[] args)
{
var comp = new FooComparer();
// this deserializes fine. woot!
using (var ms = new MemoryStream())
{
Console.WriteLine("Serializing an empty Foo");
var args1 = new Foo();
Serializer.Serialize(ms, args1);
ms.Position = 0;
var result = Serializer.Deserialize(ms);
Console.WriteLine("Serialization successful: {0}", comp.Equals(args1, result));
Console.WriteLine();
}
// this deserializes incorrectly
using (var ms = new MemoryStream())
{
Console.WriteLine("Serializing a Foo with just a string");
var args1 = new Foo("576000BJ1");
Serializer.Serialize(ms, args1); …Run Code Online (Sandbox Code Playgroud) 使用protobuf-net v2 build 668,我正在尝试序列化/反序列化一个类,该类包含一个定义为接口的成员,同时进行即时转换.通常,代理方法可以正常工作,但由于C#不允许用户定义的接口转换,我无法定义转换.
谢谢,
namespace ProtoBufNetTest
{
using System.Diagnostics;
using System.IO;
using ProtoBuf;
using ProtoBuf.Meta;
class Program
{
static void Main()
{
RuntimeTypeModel.Default.Add(typeof(IDummy), false)
.SetSurrogate(typeof(DummySurrogate));
var container = new Container { Data = new Dummy { Positive = 3 } };
using (var file = File.Create("test.bin"))
{
Serializer.Serialize(file, container);
}
using (var file = File.OpenRead("test.bin"))
{
container = Serializer.Deserialize<Container>(file);
Debug.Assert(container.Data.Positive == 3);
}
}
}
// Outside of the project, cannot be changed
public interface IDummy
{
int Positive …Run Code Online (Sandbox Code Playgroud) 据我所知,从v2开始的protobuf-net支持引用。
我目前正在尝试在可能发生如下循环引用的数据结构中使用它:
[ProtoContract]
internal class WaypointDatabase
{
[ProtoMember(1)]
public List<Waypoint> Waypoints { get; set; }
}
[ProtoContract(AsReferenceDefault = true)]
internal class Waypoint
{
[ProtoMember(1)]
public string Ident { get; set; }
[ProtoMember(2)]
public List<Route> Routes { get; set; }
}
[ProtoContract]
internal class Route
{
[ProtoMember(1)]
public Waypoint PreviousWaypoint { get; set; }
[ProtoMember(2)]
public Waypoint NextWaypoint { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
因此,使用protobuf-net序列化的主要对象是的实例WaypointDatabase。该对象包含Waypoints一个列表,Routes该列表Waypoints再次指向。
我要使用此数据结构的原因是,某些航路点未包含在路径中/未由路径引用。因此,我需要此路标数据库来跟踪所有路标,无论它们是否在现有路线内。
现在,当我尝试序列化WaypointDatabaseprotobuf-net 的实例时,我得到一个StackOverflowException,但我不明白为什么,因为我将该Waypoint类标记为,AsReferenceDefault并且我认为这将确保protobuf-net仅在使用引用时才存储该引用。再次(并且这种方式不应无限地遵循循环参考)。 …