1

有这样的 .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,对于第二个“object1”可以等于 1。获取 object1 的必要方法也是按字段名称重复计数:

public int GetFieldCount(string fieldName)

并且还需要类似的方式来访问子对象到任何嵌套级别。那可能吗?是否有替代协议缓冲区硬编码类的方法?

4

3 回答 3

0

与 xml/protobuf 对话有关;我的理解是 protobuf-csharp-port 使用不可变类型,因此不适用于 XmlSerializer 之类的东西。相比之下,protobuf-net 故意开始使用标准可变 POCO 类型,无论是您现有的 DTO,还是通过 protoprotogen 从 .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

于 2012-04-16T05:31:16.650 回答
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”字面量访问字段。你有什么想法?

于 2012-04-16T12:40:49.597 回答
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派生的所有类型。将回到它。;)

于 2012-04-17T17:01:25.603 回答