2013-05-17 8 views
6

私はこれについて完全に混乱しています。私は周りを見て、直接の答えを見つけることができないようです。 .protoファイルを持っています。私のプロジェクトは、すべてJavaであり、いくつかのメッセージを作成するために使用されています。protobuf-net - .protoから生成されたクラス - 繰り返しフィールドはセッターなしで読み取り専用になっていますか?

情報フィールドが繰り返し表示されます。私たちが作成したタイプです。 protogenでC#クラスを生成すると、このフィールドは読み込み専用となり、セッターはありません。

このパラメータを使用しないと、メッセージを完全に構築することはできません。だから私の質問です。繰り返しフィールドはこのように生成されるはずですが、私はこの読み込み専用にアクセスすることになっていますか?これは発電機のバグですか?

生成されたコード:

private readonly global::System.Collections.Generic.List<StringMapEntry> _factoryProperty = new global::System.Collections.Generic.List<StringMapEntry>(); 
[global::ProtoBuf.ProtoMember(2, [email protected]"factoryProperty", DataFormat = global::ProtoBuf.DataFormat.Default)] 
public global::System.Collections.Generic.List<StringMapEntry> factoryProperty 
{ 
    get { return _factoryProperty; } 
} 

プロトファイルのセクション:私はおそらく、本当に何かを明らかに行方不明になった

repeated StringMapEntry factoryProperty = 2; 

。助けてくれてありがとう!

var order = new Order(); 
order.Lines.Add(new OrderLine {...}); 

サブコレクションが取得するだけであるためにそれは実際にはかなり一般的です:

答えて

10

リストは、あなたはそれはあなたにを与えるリストを変異させる...読み取り専用ではありません。それはあなたが内容を変更することができないことを意味しません。

+0

リストは私的な読み取り専用として作成されていますが、私はそれをいかに混乱させるか分かりません。私は後でそれを見なければならないだろうが、私たちは問題に対する別のアプローチを使い、これを忘れてしまった。たぶん私は目が見えないのです。しかし、助けてくれてありがとう!これがあれば、私は戻ってきて、それに答えてマークします。 – Pewsplosions

+0

@userパブリックプロパティが必要です。ありませんか? –

+0

私はメインのポストをコードで更新しますが、私はまだそれをもう一度チェックするチャンスがありません。 – Pewsplosions

0

これはproto-netの実行可能ファイルと関連ファイルを更新した後の私たちの新しい問題でした。以前経験したことのない新しい行動でした。私はプライベートフィールドとセッターのための特定の部分を引き抜いてきた

<xsl:template match="FieldDescriptorProto[label='LABEL_REPEATED']"> 
    <xsl:variable name="type"><xsl:apply-templates select="." mode="type"/></xsl:variable> 
    <xsl:variable name="format"><xsl:apply-templates select="." mode="format"/></xsl:variable> 
    <xsl:variable name="field"><xsl:apply-templates select="." mode="field"/></xsl:variable> 
    private <xsl:if test="not($optionXml)">readonly</xsl:if> global::System.Collections.Generic.List&lt;<xsl:value-of select="$type" />&gt; <xsl:value-of select="$field"/> = new global::System.Collections.Generic.List&lt;<xsl:value-of select="$type"/>&gt;(); 
    [<xsl:apply-templates select="." mode="checkDeprecated"/>global::ProtoBuf.ProtoMember(<xsl:value-of select="number"/>, [email protected]"<xsl:value-of select="name"/>", DataFormat = global::ProtoBuf.DataFormat.<xsl:value-of select="$format"/><xsl:if test="options/packed='true'">, Options = global::ProtoBuf.MemberSerializationOptions.Packed</xsl:if>)]<!-- 
    --><xsl:if test="$optionDataContract"> 
    [global::System.Runtime.Serialization.DataMember([email protected]"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>, IsRequired = false)] 
    </xsl:if><xsl:if test="$optionXml"> 
    [global::System.Xml.Serialization.XmlElement(@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>)] 
    </xsl:if> 
    public global::System.Collections.Generic.List&lt;<xsl:value-of select="$type" />&gt; <xsl:call-template name="pascal"/> 
    { 
     get { return <xsl:value-of select="$field"/>; }<!-- 
     --><xsl:if test="$optionXml"> 
     set { <xsl:value-of select="$field"/> = value; }</xsl:if> 
    } 
    </xsl:template> 

csharp.xsltで少し掘削した後、私たちは、「繰り返し」フィールドの定義を見つけました

private <xsl:if test="not($optionXml)">readonly</xsl:if> ...snip... 

public ...snip... 
{ 
    ...snip... 
    <!----><xsl:if test="$optionXml"> 
    set { <xsl:value-of select="$field"/> = value; } 
    </xsl:if> 
} 

上記の疑わしい条件を$ optionXmlに注意してください。それらを単に削除すると、フィールドはもはや読み込み専用でなくなり、セッターが正しく生成されます。

だから、その後、次のようになります。 プライベート...スニップ...

public ...snip... 
{ 
    ...snip... 
    set { <xsl:value-of select="$field"/> = value; } 
} 

全 '固定' テンプレート:

<xsl:template match="FieldDescriptorProto[label='LABEL_REPEATED']"> 
    <xsl:variable name="type"><xsl:apply-templates select="." mode="type"/></xsl:variable> 
    <xsl:variable name="format"><xsl:apply-templates select="." mode="format"/></xsl:variable> 
    <xsl:variable name="field"><xsl:apply-templates select="." mode="field"/></xsl:variable> 
    private global::System.Collections.Generic.List&lt;<xsl:value-of select="$type" />&gt; <xsl:value-of select="$field"/> = new global::System.Collections.Generic.List&lt;<xsl:value-of select="$type"/>&gt;(); 
    [<xsl:apply-templates select="." mode="checkDeprecated"/>global::ProtoBuf.ProtoMember(<xsl:value-of select="number"/>, [email protected]"<xsl:value-of select="name"/>", DataFormat = global::ProtoBuf.DataFormat.<xsl:value-of select="$format"/><xsl:if test="options/packed='true'">, Options = global::ProtoBuf.MemberSerializationOptions.Packed</xsl:if>)]<!-- 
    --><xsl:if test="$optionDataContract"> 
    [global::System.Runtime.Serialization.DataMember([email protected]"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>, IsRequired = false)] 
    </xsl:if><xsl:if test="$optionXml"> 
    [global::System.Xml.Serialization.XmlElement(@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>)] 
    </xsl:if> 
    public global::System.Collections.Generic.List&lt;<xsl:value-of select="$type" />&gt; <xsl:call-template name="pascal"/> 
    { 
     get { return <xsl:value-of select="$field"/>; } 
     set { <xsl:value-of select="$field"/> = value; } 
    } 
    </xsl:template> 

を「私はfalseにoptionXml設定でプレイしますが、それはdidnのとにかくそのオプションを有効にしたい場合があります。

+0

'set'を持たないということは' msg.field = null; 'や' msg.field = otherList; 'を実行できないということです。' msg.field.Clear(); 'や' 'msg.field.AddRange(otherList);'。 –

関連する問題