2013-05-17 6 views
6

Jestem całkowicie zdezorientowany. Rozejrzałem się i nie mogę znaleźć bezpośredniej odpowiedzi. Mam plik .proto, którego mój projekt, który był wszystkim java, używa do tworzenia niektórych wiadomości.protobuf-net - wygenerowana klasa z .proto - Czy powtarzające się pole powinno być tylko do odczytu bez settera?

Istnieje powtarzające się pole informacyjne. Który jest typem, który stworzyliśmy. Kiedy generuję klasy C# z protogenem, to pole pojawia się jako tylko do odczytu i nie ma ustawnika.

Nie mogę w pełni utworzyć wiadomości bez tego parametru. Moje pytanie brzmi. Czy powtarzające się pola powinny być generowane w ten sposób i mam mieć dostęp do tej listy tylko do odczytu w inny sposób? Czy jest to błąd w generatorze?

Wygenerowany kod:

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; } 
} 

Proto sekcji pliku:

repeated StringMapEntry factoryProperty = 2; 

byłem chyba tylko brakuje czegoś naprawdę oczywiste. Dzięki za pomoc!

Odpowiedz

10

Lista nie jest tylko do odczytu ... Po prostu mutować lista daje:

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

To jest rzeczywiście dość powszechne dla sub-collections się dostać tylko. To nie znaczy, że nie możesz zmienić zawartości.

+0

Lista została utworzona jako prywatna wersja do odczytu, chyba nie widzę jak z nią zadzierać. Będę musiał to później sprawdzić, użyliśmy innego podejścia do problemu i zapomniałem o tym. Prawdopodobnie jestem tylko ślepy. Dzięki za pomoc! Jeśli tak właśnie było, wrócę i zaznaczę odpowiedź. – Pewsplosions

+0

@user powinien być własnością publiczną. Czy nie ma? –

+0

Będę aktualizował główny post za pomocą kodu, ale nadal nie mam szansy na sprawdzenie go ponownie. – Pewsplosions

0

To był nowy problem także po aktualizacji naszego pliku wykonywalnego proto-net i powiązanych plików. To było nowe zachowanie, którego wcześniej nie doświadczyliśmy.

Po trochę kopania w csharp.xslt, okazało się, że definicja pola „powtarzająca się”:

<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> 

ja wyciągnąłem konkretnych części w polu prywatnym i ustawiająca:

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> 
} 

Zwróć uwagę na warunki podejrzane powyżej dla $ optionXml. Jeśli je po prostu usuniesz, pole nie będzie już tylko do odczytu, a seter poprawnie wygenerowany.

Więc to wówczas postać: prywatny ... ciach ...

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

Full 'stałe' Szablon:

<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> 

grałem z ustawieniem optionXml false, ale nie zrobił” t działa, a mimo to nadal możesz włączyć tę opcję.

+0

Brak 'set' oznacza po prostu niemożność zrobienia' msg.field = null; 'lub' msg.field = otherList; 'To nie przeszkadza ci wykonać' msg.field.Clear(); 'lub 'msg.field.AddRange (otherList);'. –

Powiązane problemy