添加代码文件后,一切都变得清晰起来。根据堆栈跟踪,您正在使用的库是 protobuf-net;但是那个 .cs 文件与 protobuf-net无关。嗯,很少。
您看,(至少)有 2 个 c#/.net protobuf 实现,我认为您将它们混合在一起:
- protobuf-csharp-port由 Jon Skeet 开发,是 Java 版本的直接端口,意思是:它遵循相同的设计原则和 API。如果您同时使用 C# 和 Java 工作,这很诱人。
- protobuf-net是由我设计的,它是一个从第一原则开始的实现,旨在成为惯用的 .NET,这意味着:它可以针对您现有的类型(基本上,像 , 等可以)以代码优先工作
XmlSerializer
,DataContractSerializer
但也支持如果需要,可以使用 .proto
令人困惑的是,它们都具有名为“protogen”的代码生成工具。AFAIK,这种命名巧合只是自然的融合/巧合,而不是计划(好的或坏的)。
从 protobuf-csharp-port 的 protogen 生成的 c# 文件将与 protobuf-csharp-port 库一起使用
从 protobuf-net 的 protogen 生成的 c# 文件将与 protobuf-net 库一起使用
这是 protobuf-net 生成的版本,包括BlockHeader
:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// Generated from: Foo.proto
namespace ConsoleApplication9
{
[global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"Blob")]
public partial class Blob : global::ProtoBuf.IExtensible
{
public Blob() {}
private byte[] _raw = null;
[global::ProtoBuf.ProtoMember(1, IsRequired = false, Name=@"raw", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue(null)]
public byte[] raw
{
get { return _raw; }
set { _raw = value; }
}
private int _raw_size = default(int);
[global::ProtoBuf.ProtoMember(2, IsRequired = false, Name=@"raw_size", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
[global::System.ComponentModel.DefaultValue(default(int))]
public int raw_size
{
get { return _raw_size; }
set { _raw_size = value; }
}
private byte[] _zlib_data = null;
[global::ProtoBuf.ProtoMember(3, IsRequired = false, Name=@"zlib_data", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue(null)]
public byte[] zlib_data
{
get { return _zlib_data; }
set { _zlib_data = value; }
}
private byte[] _lzma_data = null;
[global::ProtoBuf.ProtoMember(4, IsRequired = false, Name=@"lzma_data", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue(null)]
public byte[] lzma_data
{
get { return _lzma_data; }
set { _lzma_data = value; }
}
private byte[] _bzip2_data = null;
[global::ProtoBuf.ProtoMember(5, IsRequired = false, Name=@"bzip2_data", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue(null)]
public byte[] bzip2_data
{
get { return _bzip2_data; }
set { _bzip2_data = value; }
}
private global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
{ return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
}
[global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"BlockHeader")]
public partial class BlockHeader : global::ProtoBuf.IExtensible
{
public BlockHeader() {}
private string _type;
[global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"type", DataFormat = global::ProtoBuf.DataFormat.Default)]
public string type
{
get { return _type; }
set { _type = value; }
}
private byte[] _indexdata = null;
[global::ProtoBuf.ProtoMember(2, IsRequired = false, Name=@"indexdata", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue(null)]
public byte[] indexdata
{
get { return _indexdata; }
set { _indexdata = value; }
}
private int _datasize;
[global::ProtoBuf.ProtoMember(3, IsRequired = true, Name=@"datasize", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
public int datasize
{
get { return _datasize; }
set { _datasize = value; }
}
private global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
{ return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
}
}
结论:
要么使用 protobuf-net protogen,要么使用 protobuf-csharp-port 库。没有混搭。