Class MsgPackArrayContractAttribute
- Namespace
- ShapeShift.MsgPack
- Assembly
- ShapeShift.MsgPack.dll
Declares that a type is serialized as a MessagePack array whose elements are identified by position (see MsgPackKeyAttribute) instead of as a map keyed by property name.
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
public sealed class MsgPackArrayContractAttribute : Attribute
- Inheritance
-
MsgPackArrayContractAttribute
- Inherited Members
Examples
var serializer = new MsgPackSerializer();
// A map contract (the default) writes property names, so it tolerates members being added,
// removed, and renamed. A positional contract writes only values, located by the permanent
// positions [MsgPackKey] assigns, which is dramatically more compact for small records.
byte[] asMap = serializer.Serialize(new MapMeasurement("t1", 21.5, 1013.2));
byte[] asArray = serializer.Serialize(new Measurement("t1", 21.5, 1013.2));
Measurement? roundTripped = serializer.Deserialize<Measurement>(asArray);
Remarks
Map contracts are the ShapeShift default because they are the most version tolerant. Positional contracts trade that tolerance for compactness: property names never appear on the wire, so a small object can shrink dramatically. Apply this attribute only when both ends of a payload are versioned together, or when the versioning rules below are followed strictly.
Versioning rules.
- Every serializable member must declare a MsgPackKeyAttribute. There is no implicit ordering.
- A key, once shipped, belongs to that member forever. Retire keys; never reuse or reorder them.
- New members take keys above every key already in use.
-
A retired key becomes a hole. Holes are written as a MessagePack
nilplaceholder whenever a later position is still written, and readers skip whatever they find at a position they no longer recognize. - A reader accepts an array that is shorter than its own contract (members at the missing positions keep their default values, subject to required-member validation) and an array that is longer (the surplus elements are skipped). That is what makes appending a member backward and forward compatible.
Omitted values. A MessagePack array has no way to say that an interior element is absent as opposed to null, so a positional contract declines SerializeDefaultValuesPolicy omission for interior positions: those members are always written, at their real values, even when that value is the default. Omission is honored only for the tail of the array, where a shorter array is an unambiguous statement that the remaining positions were not written. Required members are never elided, because a reader could not reconstruct the object without them.
Unsupported combinations. A positional contract cannot carry an extension-data member (ShapeShiftExtensionDataAttribute): unknown positions have no names to retain them under. Applying both raises a ShapeShiftSerializationException when the converter is built.