-
-
Notifications
You must be signed in to change notification settings - Fork 3
Member Formats
There are two possible formats:
- Compact - plain Google Protocol Buffers format without null support and reference tracking.
- Enhanced - not compatible with
Compact
, reading is compatible between different enhanced write modes:
- MinimalEnhancement - has null support but still can be applied to non-nullable types.
- Reference - adds reference tracking, includes MinimalEnhancement.
- LateReference - indicates that the value should not be traversed recursively, includes Reference.
You can specify desired mode on a type using an attribute. In this example Person
will be serialized with null support:
[SerializableType(ValueFormat.MinimalEnhancement)]
class Person
{
}
[SerializableType]
class Foo
{
[SerializableMember(1)]
public Person PersonData { get; set; }
}
Or using code mapping:
RuntimeTypeModel model = TypeModel.Create();
model.Add(typeof(Person), true).DefaultFormat = ValueFormat.MinimalEnhancement;
[SerializableType]
class Foo
{
[SerializableMember(5, ValueFormat.Reference)]
public Person PersonData { get; set; }
}
Or using code mapping:
model.Add(typeof(Foo), true)[5]
.SetSettings(x => x.V.Format = ValueFormat.Reference);
[SerializableType]
class Foo
{
[SerializableMember(5)] // List<Person>
[SerializableMemberNested(/* nested level: */ 1, ValueFormat.Reference)] // Person
public List<Person> PersonData { get; set; }
}
Or using code mapping:
model.Add(typeof(Foo), true)[5]
.SetSettings(x => x.V.Format = ValueFormat.Reference,
/* nested level: */ 1);
When a mode is not specified neither on a type nor on a member it's determined automatically:
Type | Default mode |
---|---|
class | Reference |
nullable? | MinimalEnhancement |
struct/enum | Compact |
Types mapped with [ProtoContract]
attributes have special rules applied:
AsReferenceDefault | Type | Mode |
---|---|---|
true | any | Reference |
false / not specified | class | MinimalEnhancement |
false / not specified | nullable? | MinimalEnhancement |
false / not specified | struct/enum | Compact |
Members mapped with [ProtoMember]
attributes (and "partial") have special rules applied:
AsReference | Final mode |
---|---|
true | Reference |
false | From the table above |
not specified | From inherited type settings or (if not specified) from the table above |
For collection members item specified settings are usually copied from [ProtoMember]
attribute (in a state before applying inherited type settings).
If you receive Recursion depth exceeded safe limit
exception LateReference mode may help you.
This mode changes reference tracking behavior to not use deep traversal ("to not go inside member recursively") but it has to write additional data and therefore it's slower. Use it only on concrete members which should not be traversed recursively like linked list nodes.
An example:
[SerializableType]
public class Node
{
[SerializableMember(1, ValueFormat.LateReference)]
public Node Next { get; set; }
[SerializableMember(2, ValueFormat.LateReference)]
public Node Prev { get; set; }
[SerializableMember(3)]
public int Value { get; set; }
}
In this mode you can't override any type settings like CollectionFormat
or specify any member-specific settings like WriteAsDynamicType
. The same rule is applied to nested levels (collection items). LateReference value is always written using type settings only without any customization.