Skip to content

Full feature list & planned features

Rikimaru edited this page Sep 20, 2019 · 28 revisions

Major Features

  • Very fast, comparable to MessagePackCSharp
  • Very small binary output
  • Full support for circular references
  • Full support for polymorphism / inheritance / interfaces
  • Can serialize objects into parts as "ExtenalObjects" (very useful for usage with databases)

Other Features

  • Serialize Fields, Properties, and even readonly fields (Check out the Tutorial to see all the different configuration options, and Feature Demos/Tests for readonly handling (check the ReadonlyTest() method) )
    • TypeConfig -> Member-Attribute -> Class-Attribute -> Global Default
  • Can serialize static classes and static variables: ceras.Advanced.SerializeStatic(type);
  • Full support for Unity, IL2CPP, UWP, iOS
  • Attribute Free
    • You're never forced to place any sort of [Key] or [Order] attributes or anything like that
    • Ceras has many attributes that you can use if you want to.
    • Fields/Props are ordered by a combination of name + type-name + declaring type name + element type + ... which means you never have to manually add something like [Order] or [Key] attributes to your classes.
  • Debug Report
    • For when you're not sure if/why some field/prop got included or not
    • Use ceras.GenerateSerializationDebugReport(type) to get a report explaining how Ceras will handle the given type, contains information about the used formatter, serialized members, and reasons for inclusion/exclusion.
  • Efficient:
    • By default no type-, versioning-, or other meta-data is written, only what is strictly needed.
    • Utilizes both VarInt & Zig-Zag encoding (example: values up to 128 only take 1 byte instead of 4...)
    • Encodes type-information in 0 or 1 byte in most cases
    • If the type already matches no types are written at all (vast majority of cases)
    • KnownTypes only use 1 byte (if the type needs to be written at all)
    • Ceras can dynamically learn new/unknown types while serializing (if activated)
    • No type lookups! (except for polymorphic types obviously)
  • Splitting: Want to save your Monster, Spell, and Player objects each into their own file, but they all reference each other in many ways? No problem! Using IExternalRootObject you can easily split out objects
  • No allocations
    • Recycles all internal objects, so it generates no "garbage" (garbage-collector pressure)
    • Integrates with user object-pools as well with ObjectFactory and DiscardObject methods. Especially useful for use as a network protocol or in games so Ceras will not allocate new user-objects and instead get them from your pools.
    • Recycles serialization buffers (just pass in the buffer by ref)
  • Can overwrite objects you already have (by using the Deserialize(ref existingObject) method). Works even when an object already contains references to wrong types, Ceras will optionally use your DiscardObject-Method then. (can be used to eliminate allocations/GC pressure).
  • Advanced caching settings to remember objects and typing information over multiple serialization calls to save even more space
  • Can be used as a very efficient binary network protocol
  • Can generate a checksum of all types, fields, attributes, ... which can be used to ensure binary compatability (very useful for networking where you want to check if the server/client are using the same protocol...)
  • Creating a custom IFormatter is very easy
    • Ceras has its own DI system to make writing a custom formatter as smooth as possible, simply declare a public IFormatter<Bla> BlaFormatter; and Ceras will automatically inject it.
  • Easy configuration of your own types through attributes ([MemberConfig], [Ignore], [Include], ...)
  • Fully automatic version tolerance. Simply turn on .VersionTolerance in the settings to let Ceras embedd schema information, so when you change your objects, Ceras can still load older data. Supports all changes: adding / renaming / reordering / deleting members.
  • Ceras is fully "reentrant" meaning that the same serializer-instance can start a new nested serialization while the other one is still in progress. Very useful when dealing with IExternalRootObjects (simplifies your code a lot).
  • Support for readonly fields: Just set ReadonlyFieldHandling.Members and Ceras will populate the contents of objects in readonly fields. Or set ReadonlyFieldHandling.ForcedOverwrite to overwrite readonly field itself as well (using reflection). (Default is Off because readonly fields are very rarely serialized)
  • Helpful exceptions: All exceptions Ceras throws contain reasons why something went wrong and what to do about it.
  • Serialization callbacks: Just put the [OnAfterDeserialize] attribute on a method. When Ceras has written all the fields/properties to the object your method will be called. (OnBeforeSerialize etc added when needed / on request)

Built-in types

Built-in support for almost everything:

  • Primitives(int, string, ...), Enum
  • All commonly used types from the C# base-class-library: decimal, DateTime, TimeSpan, DateTimeOffset, Guid, Array[], KeyValuePair<,>, Nullable<>, BitVector32, BigInteger, Tuple<>, ValueTuple<>, ...
  • Anything that implements ICollection<>: so List<>, Dictionary<,>, ... Also ReadonlyCollection<> and its derivatives!
  • Multidimensional arrays T[,], T[,,], ...
  • NuGet package for System.Collections.Immutable.*
  • Expression Trees: All types in System.Linq.Expressions.*!
  • Can serialize the full CLR type system
    • Can serialize the Type-Type itself
    • All derivatives of MemberInfo (FieldInfo, MethodInfo, ConstructorInfo, MethodBase, ...)
    • Full support for closed, open, and half-open generic types and even MethodInfos
  • Can serialize delegate, MulticastDelegate, System.Action<...>, System.Func<...>, ... (if activated in the config)
  • Ceras uses dynamic code generation to support any new/user-type
  • Support for types in UnityEngine.*
  • System.Drawing.Bitmap and Color

Something missing? Just open an issue! 😄

Planned features

This list is quite long, I put pretty much every idea I have here (or ideas suggested by the community). If you urgently need any of those just let me know. Entries are in no particular order.

Done

  • Allow overriding formatters: config.ConfigType<...>().SetFormatter(...)
  • Support for IL2CPP for Unity (AotMode + generator tool to write formatters for all user-types automatically)
  • Wider range of unit tests instead of manual test cases / debug asserts
  • Some sort of log that tells you exactly what members are included in the serialization and why, and why the excluded ones are excluded, and what Ceras has tried to determine inclusion/exclusion. Maybe something like ceras.GenerateSerializationDebugReport(typeof(MyType));
  • It would be really cool to support the "capacity-constructor" for List<>, Dictionary<> etc... Shouldn't even be that hard to do and improve performance somewhat when dealing with large collections.
  • VersionTolerance could be optimized a bit (if anyone even needs that). We could have settings for the field-size-prefix; or maybe also allow changing the type of a field/property and allow the user to provide some sort of converter. We could also embed a hash per schema and skip reading it when we already have that schema (which improves reading speed)
  • Use array pool, create a new api to help total beginners by managing buffers for them?
  • "Serialization Constructors" for immutable collections (also supporting private static methods for construction)
  • Open up delegate serialization more to allow instance-bound delegates as well (configurable through a setting and Off by default of course, since that stuff can be pretty dangerous :P !)
  • Support ReadonlyCollection<>
  • Full support to serialize Expression-Trees System.Linq.Expressions.* (currently WIP...)
  • Capacity constructors, making use of the new List<T>(capacity) overload when deserializing List<>, Dictionary<>, ...
  • Hand-crafted Formatters for all common Unity3D types
  • Configurable size/length limits for strings, arrays, collections; to protect against malicious data (interesting for networking scenarios).
  • Performance comparisons beyond simple micro benchmarks
  • Handling for readonly fields
  • .NET standard build target
  • Making Ceras available as a nuget package
  • Automatic release builds
  • Automatic version tolerance can now be enabled through config. config.VersionTolerance = VersionTolerance.AutomaticEmbedded;. More options will follow in the future including manual version tolerance if you want to go the extra mile to optimize your code.
  • Ceras supports fields and properties now, checkout the tutorial.cs file to see all the ways to configure what gets serialized
  • Serialize/Deserialize callbacks. Just put the [OnAfterDeserialize] attribute on a method. When Ceras has written all the fields/properties to the object your method will be called. More attributes (like OnBeforeDeserialize or whatever) can be easily added, just open an issue on github :)

Future / on request

  • Better exceptions (specific types per for each exception so they can be individually caught)
  • Use FastExpressionCompiler when all its bugs are fixed
  • Built-in LZ4 and GZip(Zlib) support, including support for Sync-Flush (especially useful for networking scenarios)
  • Allow overriding the used formatter per field. Not sure in what situations that'd be useful though, so not very high on the priority list...
  • Maybe use Span<> instead of byte arrays, is it possible/compatible with EnsureCapacity?
  • Improved string encoding performance when C# gets native Utf8 strings