2013-05-17 19 views
6

Tôi hoàn toàn bối rối về điều này. Tôi đã nhìn xung quanh và dường như không thể tìm thấy câu trả lời trực tiếp. Tôi có một tệp .proto mà dự án của tôi, tất cả đều là java, sử dụng để tạo một số thư.protobuf-net - tạo ra lớp từ .proto - Trường lặp lại được cho là chỉ đọc mà không có setter?

Có trường Thông tin lặp lại. Đó là một loại chúng tôi tạo ra. Khi tôi tạo ra các lớp C# với protogen, trường này xuất hiện dưới dạng chỉ đọc và không có setter.

Tôi không thể xây dựng hoàn toàn thư mà không có tham số này. Vì vậy, câu hỏi của tôi là. Các trường lặp lại được cho là được tạo ra như thế này và tôi được cho là đang truy cập vào chỉ đọc này Liệt kê một số cách khác? Hay đây là một lỗi trong máy phát?

Tạo mã:

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 tập tin phần:

repeated StringMapEntry factoryProperty = 2; 

tôi có lẽ chỉ còn thiếu một cái gì đó thực sự rõ ràng. Cảm ơn vì bất kì sự giúp đỡ!

Trả lời

10

Danh sách này không được chỉ đọc ... Bạn chỉ cần đột biến danh sách nó mang lại cho bạn:

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

Nó thực sự là khá phổ biến đối với phụ bộ sưu tập được lấy-only. Điều đó không có nghĩa là bạn không thể thay đổi nội dung.

+0

Danh sách được tạo thành riêng tư chỉ đọc, tôi đoán tôi chỉ không thấy làm thế nào để gây rối với nó. Tôi sẽ phải xem xét nó sau này mặc dù, chúng tôi sử dụng một cách tiếp cận khác nhau cho vấn đề và tôi quên mất điều này. Có lẽ chỉ là tôi bị mù. Cảm ơn sự giúp đỡ của bạn! Nếu đây là những gì tôi sẽ trở lại và đánh dấu nó trả lời. – Pewsplosions

+0

@user phải có tài sản công cộng. Có phải không? –

+0

Tôi sẽ cập nhật bài đăng chính bằng mã, tôi vẫn chưa có cơ hội để kiểm tra lại. – Pewsplosions

0

Đây là vấn đề mới đối với chúng tôi cũng như sau khi cập nhật tệp thực thi nguyên bản và các tệp có liên quan. Đó là hành vi mới mà trước đây chúng tôi chưa từng trải qua.

Sau một đào nhỏ trong csharp.xslt, chúng tôi thấy định nghĩa cho các lĩnh vực 'lặp lại':

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

Tôi đã rút khỏi các phần cụ thể cho lĩnh vực tư nhân và setter:

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

Lưu ý các điều kiện nghi ngờ ở trên cho $ optionXml. Nếu bạn chỉ cần loại bỏ những người, lĩnh vực này không còn readonly và setter được tạo ra đúng cách.

Vì vậy, nó sau đó trở thành: tin ... snip ...

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

Full 'cố định' mẫu:

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

tôi chơi với thiết optionXml false, nhưng nó didn' t làm việc và bạn vẫn có thể muốn kích hoạt tùy chọn đó.

+0

Không có 'set' chỉ có nghĩa là bạn không thể thực hiện' msg.field = null; 'hoặc' msg.field = otherList; 'Nó không ngăn bạn thực hiện' msg.field.Clear(); 'hoặc 'msg.field.AddRange (otherList);'. –

Các vấn đề liên quan