Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Protobuf网络和流:未设置流时InvalidCastException。位置=0_C#_Protobuf Net - Fatal编程技术网

C# Protobuf网络和流:未设置流时InvalidCastException。位置=0

C# Protobuf网络和流:未设置流时InvalidCastException。位置=0,c#,protobuf-net,C#,Protobuf Net,如果我想用protobuf net反序列化序列化对象,为什么必须手动将序列化对象的流位置设置为0 我希望protobuf net总是从一开始就读取我的输入流 如果我想让protobuf net从不同的偏移位置读取我的流(比如通过标记读取类或列表的成员),我会假设这是一个例外的用例,我必须有意识地处理它(api方面) (我的protobuf net版本是640。) 下面是我的测试用例,它使用继承引发了一个异常: 使用System.IO; 使用ProtoBuf; 名称空间ProtobufStream

如果我想用protobuf net反序列化序列化对象,为什么必须手动将序列化对象的流位置设置为0

我希望protobuf net总是从一开始就读取我的输入流

如果我想让protobuf net从不同的偏移位置读取我的流(比如通过标记读取类或列表的成员),我会假设这是一个例外的用例,我必须有意识地处理它(api方面)

(我的protobuf net版本是640。)

下面是我的测试用例,它使用继承引发了一个异常:

使用System.IO;
使用ProtoBuf;
名称空间ProtobufStreamTest
{
公共班级1
{
静态公共void Main(字符串[]args)
{
var inheritingModel=新的inheritingModel()
{
继承ModelMember1=“TestInWriting”,
BaseModelMember1=42,
};
var ms=新内存流();
ProtoBuf.Serializer.Serialize(ms,继承模型);
var originalStreamPos=ms.位置;//==33
//ms.位置=0;//
如果我想用protobuf net反序列化序列化对象,为什么必须手动将序列化对象的流位置设置为0

这是任何接受
流的API的正常做法;事实上,许多(大多数?)流是不可查找的。自动尝试重置位置是非常不寻常的

我希望protobuf net总是从一开始就读取我的输入流。如果我想让protobuf net从不同的偏移位置读取我的流(如通过标记读取类或列表的成员),我会假设这是一个例外的用例,我必须有意识地处理它(api方面)

我非常不希望如此。这根本不是
Stream
s的使用方式-与protobuf net无关,而是更多:在一般情况下。尝试一下任何API(序列化、压缩、加密、数据传输等):你会发现几乎所有的API都会以同样的方式工作,我认为那些没有(但是:重置位置)是不正确的实现

原因有两个基本部分:

  • 因为许多流是不可搜索的,所以使用者永远不应该假设它可以将位置重置为零;对于可搜索和不可搜索,它也不应该有两种截然不同的行为——因此,唯一表现良好的实现是:不要假设你可以搜索
  • 在许多情况下,一个流被分为多个部分使用-即,它可能是300字节的X,然后是200字节的Y,然后是12字节的Z;当读取Y和Z时,如果流不断重置,这将是灾难性的和意外的(即几乎没有API会这样做)

基本上;您的期望不是正常情况。

btw;如果您的目的是序列化,重置为零,然后反序列化-那么我觉得您应该使用
var clone=Serializer.DeepClone(继承模型)
-基本上就是这么做的谢谢指针,但上面的代码只是一个测试用例。谢谢Marc,我接受;)也许我的期望源于我过去使用的流不可查找的事实。我在ServiceStack中使用PreRequestHeader时首先遇到了这种行为,并假设它与protobuf相关:在protobuf net生效之前读取Request.InputStream时,我遇到了protobuf net c的上述行为ouldn不再序列化(因为流的位置在末尾)。另一方面:我必须承认,对于不喜欢流的人来说,上面显示的行为很难确定,因为protobuf net的行为感觉有点不确定(->继承异常,无继承异常等).@derFunk零长度有效负载完全有效且有意义是protobuf规范的一个特点;因此,不幸的是,从流末尾错误地反序列化与反序列化真正为空的数据没有明显区别。在继承的情况下,您需要一个子类(而不是基类),拥有一个零长度的有效负载确实是不正确的,但对于这一场景来说,这似乎是人为的。例如,如果您的示例不是继承,它不会出错-它在各个方面都是不可检测的-只是没有值。