-
-
Notifications
You must be signed in to change notification settings - Fork 3
Collections
Collection types use a special handling and can't have serializable members. You may want your type to be handled not as a collection:
[SerializableType(IgnoreListHandling = true)]
class NotACollection : IList<int>
{
// ...
}
Or the same using code mapping:
RuntimeTypeModel model = TypeModel.Create();
model.Add(typeof(NotACollection), true).IgnoreListHandling = true;
- Enhanced - own format incompatible with Protocol Buffers.
- Protobuf - Protocol Buffers format when all primitive types are packed.
- ProtobufNotPacked - old Protocol Buffers format without packing support.
All of them are incompatible between each other (except that changing from ProtobufNotPacked
to Protobuf
is possible).
The default format is Enhanced
but in compatibility mode it's replaced with Protobuf
.
- Nested collections support.
- Multidimensional arrays support (in addition to single-dimensional).
- Empty arrays are not treated the same as null and vice versa.
- Collection subtype information is preserved.
- Always packed for better output size, also applied to non-primitive types.
- Supported referencing an array from inside itself.
For not nested root collections without a contract attribute (SerializableType, DataContract, etc) the Auxiliary mode is used unless a collection type is explicitly registered with model.Add
or by using serializable member of such collection type. You can disable this behavior by specifying model.AlwaysUseTypeRegistrationForCollections = true
.
The purpose of this mode is to allow serialization of unknown collection types when an item type is registered. It may be useful for precompiled models where adding a new collection type is not possible.
Auxiliary serialization always uses GoogleNotPacked
format.
You can specify desired format on a type using an attribute. In this example Persons
will be serialized using Protobuf collection format:
[SerializableType(CollectionFormat = CollectionFormat.Protobuf)]
class PersonList : List<string>
{
}
[SerializableType]
class Foo
{
[SerializableMember(1)]
public PersonList Persons { get; set; }
}
Or using code mapping:
RuntimeTypeModel model = TypeModel.Create();
model.Add(typeof(PersonList), true).CollectionFormat = CollectionFormat.Protobuf;
[SerializableType]
class Foo
{
[SerializableMember(5, CollectionFormat = CollectionFormat.Enhanced)]
public PersonList Persons { get; set; }
}
Or using code mapping:
model.Add(typeof(Foo), true)[5]
.SetSettings(x => x.V.Collection.Format = CollectionFormat.Enhanced);
[SerializableType]
class Foo
{
[SerializableMember(5)]
[SerializableMemberNested(/* nested level: */ 1, CollectionFormat = CollectionFormat.Enhanced)]
public List<PersonList> ListOfListOfPersons { get; set; }
}
Or using code mapping:
model.Add(typeof(Foo), true)[5]
.SetSettings(x => x.V.Collection.Format = CollectionFormat.Enhanced,
/* nested level: */ 1);
[SerializableType]
class Foo
{
[SerializableMember(5, CollectionFormat = CollectionFormat.ProtobufNotPacked)] // List<PersonList>
[SerializableMemberNested(/* nested level: */ 1, CollectionFormat = CollectionFormat.Enhanced)] // PersonList
public List<PersonList> ListOfListOfPersons { get; set; }
}
Or using code mapping:
model.Add(typeof(Foo), true)[5]
.SetSettings(x => x.V.Collection.Format = CollectionFormat.ProtobufNotPacked);
model.Add(typeof(Foo), true)[5]
.SetSettings(x => x.V.Collection.Format = CollectionFormat.Enhanced,
/* nested level: */ 1);
For members mapped with protobuf-net attributes:
IsPacked | Proto compatibility mode | Format |
---|---|---|
false / not specified | false | Inherited from a type of value / default |
false / not specified | true | ProtobufNotPacked |
true | false | Protobuf |
true | true | Protobuf |