有这样的.proto文件结构
{
session{
field1 = value;
field2 = value;
...
}
object1{
Object1field1 = value;
Object1field2 = value;
...
}
object1{
Object1field1 = value;
Object1field2 = value;
...
}
object2{
Object2field1 = value;
Object2field2 = value;
...
SubObject1{
SubObject1field1 = value;
SubObject2field2 = value;
...
}
} object2{
Object2field1 = value;
Object2field2 = value;
...
SubObject1{
SubObject1field1 = value;
SubObject2field2 = value;
...
}
}
} 简单地说有复杂的层次结构。例如,Object1或Object2可以是可重复的。是否有可能编写通用方法,将字段值作为基础对象返回,如int,bool,string,datetime或简单的字符串?我希望通过字符串文字获得以下访问权限:
public object GetFieldValue(int number, string fullPath)
可以像这样指定fullPath,例如:
fullPath = "object1.Object1field1";
重复字段所需的数量:例如,对于第一个“object1”,number可以等于0,对于第二个字段,可以等于1。获取object1重复的必要方法也是按字段名称计算的:
public int GetFieldCount(string fieldName)
并且还需要类似的方式来访问SubObjects到任何嵌套级别。那可能吗?是否存在协议缓冲区硬编码类的替代方法?
答案 0 :(得分:0)
与xml / protobuf对话有关;我的理解是protobuf-csharp-port使用不可变类型,因此不适用于像XmlSerializer这样的东西。相比之下,protobuf-net故意开始使用标准的可变POCO类型,无论是现有的DTO,还是通过protprotogen从.proto生成;无论哪种方式,我们最终得到的生成类型如下:
[ProtoContract]
public class Foo {
[ProtoMember(1)]
public string Name {get;set;}
[ProtoMember(2)]
public Bar Something {get;set;}
}
[ProtoContract]
public class Bar {
[ProtoMember(1)]
public int Id {get;set;}
}
(给予或采取一些复杂性)
然后从protobuf流转换为xml就是:
Foo foo;
using(var source = ...) {
foo = Serializer.Deserialize<Foo>(source);
}
string xml;
using(var sw = new StringWriter()) {
var ser = new Serializer(typeof(Foo));
ser.Serialize(sw, foo);
xml = sw.ToString();
}
现在xml
是XmlSerializer
实例中相同数据的Foo
表示形式(以及任何子数据,例如Bar
)
答案 1 :(得分:0)
顺便说一句,如果您将代码生成扩展为以下内容会怎样:
[ProtoContract]
public class Foo : IGetFieldsByName {
[ProtoMember(1)]
public string Name {get;set;}
[ProtoMember(2)]
public Bar Something {get;set;}
}
[ProtoContract]
public class Bar : IGetFieldsByName {
[ProtoMember(1)]
public int Id {get;set;}
}
即。从同一个接口IGetFieldsByName继承所有类?然后很容易实现我喜欢的行为:通过“object.name”文字访问字段。你怎么看?
答案 2 :(得分:0)
嗯......绝对是protobuf-csharp-port拥有此任务所需的一切,例如:
IMessage object2 = (IMessage)original[original.DescriptorForType.FindFieldByName("object2"), 0];
IMessage subObject1 = (IMessage)object2[object2.DescriptorForType.FindFieldByName("SubObject1")];
int value = (int)subObject1[subObject1.DescriptorForType.FindFieldByName("SubObject1Field1")];
所有类型均来自 IMessage 。会回归它。 ;)