Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.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# 列表的协议缓冲区序列化_C#_.net_Protobuf Net - Fatal编程技术网

C# 列表的协议缓冲区序列化

C# 列表的协议缓冲区序列化,c#,.net,protobuf-net,C#,.net,Protobuf Net,以下代码有什么问题 MyList l = Serializer.DeepClone(new MyList { "abc" }); Console.WriteLine(l.Count == 1); 其中: [ProtoContract] public class MyList : List<String> { } [协议] 公共类MyList:列表 { } 期望值:真,实际值:假。我自己刚刚完成一个项目,在那里我正在使用Protobut,并在项目中使用了大约30个不同的Proto

以下代码有什么问题

MyList l = Serializer.DeepClone(new MyList { "abc" });
Console.WriteLine(l.Count == 1);
其中:

[ProtoContract]
public class MyList : List<String>
{
}
[协议]
公共类MyList:列表
{
}

期望值:真,实际值:假。

我自己刚刚完成一个项目,在那里我正在使用Protobut,并在项目中使用了大约30个不同的ProtoContract,我只是回顾了一下,因为我认为我做了类似的工作,但事实上我从来没有直接做过这个特定的案例

所以我只是把它作为一个测试,但你可以把它用于你的目的。(是的,这是VB,但我现在比C快多了[但我已经做到了])

结果不是我期望的,所以我把我的测试贴在这里。也许你可以用内部列表实现这个类(现在就让你完成)

Mylist ProtoBuf False

Mylist二进制格式化程序True

Mylist2 ProtoBuf True

MyListI ProtoBuf假

MyListThing ProtoBuf False

Imports System.IO
进口ProtoBuf
公开课入学
共享子主目录()
Dim l作为新的MyList
l、 添加(“abc”)
将新列表设置为MyList
使用ms作为新的内存流
序列化程序。序列化(MyList的)(ms,l)
ms.Seek(0,SeekOrigin.Begin)
newList=序列化程序。反序列化(MyList的)(ms)
终端使用
WriteLine(“Mylist ProtoBuf{0}”,newList.Count=1)
Dim f作为新的System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
使用ms作为新的内存流
f、 序列化(ms,l)
ms.Seek(0,SeekOrigin.Begin)
newList=CType(f.反序列化(ms),MyList)
终端使用
WriteLine(“Mylist二进制格式化程序{0}”,newList.Count=1)
Dim l2作为新MyList2
l2.项目。添加(“abc”)
将新列表2变暗为MyList2
使用ms作为新的内存流
序列化程序。序列化(MyList2)(ms,l2)
ms.Seek(0,SeekOrigin.Begin)
newList2=序列化程序。反序列化(MyList2的)(ms)
终端使用
WriteLine(“Mylist2 ProtoBuf{0}”,newList2.Items.Count=1)
朦胧的李作为新的MyListI
李.加(5)
我的名字叫Dim newListi
使用ms作为新的内存流
序列化程序。序列化(MyListI)(ms,li)
ms.Seek(0,SeekOrigin.Begin)
newListi=序列化程序。反序列化(MyListI的)(ms)
终端使用
WriteLine(“MyListI ProtoBuf{0}”,newListi.Count=1)
暗lh作为新的MyListThing
Add(newthing()和{.Message=“abc”})
朦胧的新感觉就像我的梦一样
使用ms作为新的内存流
序列化器。序列化(MyListThing)(ms,lh)
ms.Seek(0,SeekOrigin.Begin)
newListh=序列化程序。反序列化(MyListThing的)(ms)
终端使用
WriteLine(“MyListThing ProtoBuf{0}”,newListh.Count=1)
端接头
末级
公共类MyList
继承(字符串的)列表
末级
公共类MyList2
公共分新()
项目=新列表(字符串)
端接头
作为列表的公共属性项(字符串)
末级
公共类MyListI
继承(整数的)列表
末级
公共类物品
继承(事物的)列表
末级
公共类事物
作为字符串的公共属性消息
末级

如果您想要立即修复,只需拿走
[ProtoContract]
;列表具有内置行为,不需要标记为合同

在这种情况下,合同定义优先于列表这一事实;我需要仔细观察,看看改变这一点是否会导致任何不必要的副作用

工作示例:

public class MyList : List<string>{}

[Test]        
public void ListSubclassShouldRoundTrip()
{
    var list = new MyList { "abc" };
    var clone = Serializer.DeepClone(list);
    Assert.AreEqual(1, clone.Count);
    Assert.AreEqual("abc", clone[0]);
}
public类MyList:List{}
[测试]
public void list子类shouldldroundtrip()
{
var list=new MyList{“abc”};
var clone=Serializer.DeepClone(列表);
Assert.AreEqual(1,clone.Count);
Assert.AreEqual(“abc”,克隆[0]);
}
当前的示例:

[ProtoContract]
public class MyContractList : List<string> { }

[Test]
public void ContractListSubclassShouldRoundTrip()
{
    var list = new MyContractList { "abc" };
    var clone = Serializer.DeepClone(list);
    Assert.AreEqual(1, clone.Count);
    Assert.AreEqual("abc", clone[0]);
}
[协议]
公共类MyContractList:List{}
[测试]
public void ContractListSubclass应往返()
{
var list=新的MyContractList{“abc”};
var clone=Serializer.DeepClone(列表);
Assert.AreEqual(1,clone.Count);
Assert.AreEqual(“abc”,克隆[0]);
}

更新;然而,这看起来应该是可行的,因为当列表是某个类型的成员时,它可以正常工作;只有当列表是图形中最外层的类型时才会出现问题。示例(所有测试均通过):

[协议]
公共类ListWrapper
{
[原成员(1)]
公共列表基本列表{get;set;}
[原成员(2)]
公共MyList MyList{get;set;}
[原成员(3)]
公共MyContractList MyContractList{get;set;}
}
[测试]
public void TestBasicListAsMember()
{
var obj=newlistwrapper{BasicList=newlist{“abc”};
var clone=Serializer.DeepClone(obj);
Assert.IsNull(clone.MyList);
Assert.IsNull(clone.MyContractList);
aresequal(1,clone.BasicList.Count);
Assert.AreEqual(“abc”,克隆.BasicList[0]);
}
[测试]
public void testMyListMember()
{
var obj=newlistwrapper{MyList=newmylist{“abc”};
var clone=Serializer.DeepClone(obj);
Assert.IsNull(clone.BasicList);
Assert.IsNull(clone.MyContractList);
aresequal(1,clone.MyList.Count);
Assert.AreEqual(“abc”,clone.MyList[0]);
}
[测试]
public void TestMyContractListAsMember()
{
var obj=newlistwrapper{MyContractList=newmycontractlist{“abc”};
var clone=Serializer.DeepClone(obj);
Assert.IsNull(clone.BasicList);
Assert.IsNull(clone.MyList);
arenequal(1,clone.MyContractList.Count);
Assert.AreEqual(“abc”,clone.MyContractList[0]);
}

更新:这是一个微妙的bug,由列表的许多不同行为方式引起;对于具有getter和setter的成员列表,它的逻辑是“如果我们得到了列表,而它不是
[ProtoContract]
public class MyContractList : List<string> { }

[Test]
public void ContractListSubclassShouldRoundTrip()
{
    var list = new MyContractList { "abc" };
    var clone = Serializer.DeepClone(list);
    Assert.AreEqual(1, clone.Count);
    Assert.AreEqual("abc", clone[0]);
}
[ProtoContract]
public class ListWrapper
{
    [ProtoMember(1)]
    public List<string> BasicList { get; set; }
    [ProtoMember(2)]
    public MyList MyList { get; set; }
    [ProtoMember(3)]
    public MyContractList MyContractList { get; set; }
}

[Test]
public void TestBasicListAsMember()
{
    var obj = new ListWrapper { BasicList = new List<string> { "abc" } };
    var clone = Serializer.DeepClone(obj);
    Assert.IsNull(clone.MyList);
    Assert.IsNull(clone.MyContractList);
    Assert.AreEqual(1, clone.BasicList.Count);
    Assert.AreEqual("abc", clone.BasicList[0]);
}

[Test]
public void TestMyListAsMember()
{
    var obj = new ListWrapper { MyList = new MyList { "abc" } };
    var clone = Serializer.DeepClone(obj);
    Assert.IsNull(clone.BasicList);
    Assert.IsNull(clone.MyContractList);
    Assert.AreEqual(1, clone.MyList.Count);
    Assert.AreEqual("abc", clone.MyList[0]);
}

[Test]
public void TestMyContractListAsMember()
{
    var obj = new ListWrapper { MyContractList = new MyContractList { "abc" } };
    var clone = Serializer.DeepClone(obj);
    Assert.IsNull(clone.BasicList);
    Assert.IsNull(clone.MyList);
    Assert.AreEqual(1, clone.MyContractList.Count);
    Assert.AreEqual("abc", clone.MyContractList[0]);
}