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、または単に string などのベース オブジェクトとしてフィールド値を返すユニバーサル メソッドを作成することは可能ですか? 文字列リテラルによる次のアクセスを取得したいと思います。

public object GetFieldValue(int number, string fullPath)

たとえば、次のように fullPath を指定できます。

fullPath = "object1.Object1field1";

繰り返しフィールドに必要な数値: たとえば、数値は最初の「object1」の場合は 0、2 番目の場合は 1 に等しくなる可能性があります。また、object1 の繰り返し回数をフィールド名で取得するために必要なメソッド:

public int GetFieldCount(string fieldName)

また、ネストされたレベルにサブオブジェクトにアクセスするための同様の方法も必要です。それは可能ですか?プロトコル バッファのハードコードされたクラスに代わるものはありますか?

4

3 に答える 3

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 に答える
0

xml/protobuf の会話に関連します。私の理解では、protobuf-csharp-port は不変型を使用するため、XmlSerializer などではうまく機能しません。対照的に、protobuf-net は、既存の DTO、または protprotogen を介して .proto から生成された標準の可変 POCO タイプを意図的に使用するように設定されています。いずれにせよ、生成された型は次のようになります。

[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内の同じデータの表現です。FooBar

于 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 に答える