typeless - fix compiler error on Unity
This commit is contained in:
Родитель
411318f91c
Коммит
9dd83054c5
33
README.md
33
README.md
|
@ -202,6 +202,8 @@ var bin2 = MessagePackSerializer.Serialize(data);
|
|||
|
||||
ContractlessStandardResolver can serialize anonymous type, too.
|
||||
|
||||
I don't need type, I want to use like BinaryFormatter! You can use as typeless resolver and helpers. Please see [Typeless](https://github.com/neuecc/MessagePack-CSharp#typeless) section.
|
||||
|
||||
Resolver is key customize point of MessagePack for C#. Details, please see [extension point](https://github.com/neuecc/MessagePack-CSharp#extension-pointiformatterresolver).
|
||||
|
||||
Serialize ImmutableObject(SerializationConstructor)
|
||||
|
@ -411,6 +413,33 @@ Console.WriteLine(dynamicModel["Items"][2]); // 100
|
|||
|
||||
So you can access indexer for msgpack map and array.
|
||||
|
||||
Typeless
|
||||
---
|
||||
Typeless API is like `BinaryFormatter`, embed type information to binary so no needs type to deserialize.
|
||||
|
||||
```csharp
|
||||
object mc = new Sandbox.MyClass()
|
||||
{
|
||||
Age = 10,
|
||||
FirstName = "hoge",
|
||||
LastName = "huga"
|
||||
};
|
||||
|
||||
// serialize to typeless
|
||||
var bin = MessagePackSerializer.Typeless.Serialize(mc);
|
||||
|
||||
// binary data is embeded type-assembly information.
|
||||
// ["Sandbox.MyClass, Sandbox",10,"hoge","huga"]
|
||||
Console.WriteLine(MessagePackSerializer.ToJson(bin));
|
||||
|
||||
// can deserialize to MyClass with typeless
|
||||
var objModel = MessagePackSerializer.Typeless.Deserialize(bin) as MyClass;
|
||||
```
|
||||
|
||||
Type information is serialized by mspgack `ext` format, typecode is 100.
|
||||
|
||||
`MessagePackSerializer.Typeless` is shortcut of `Serialize/Deserialize<object>(TypelessContractlessStandardResolver.Instance)`. If you want to configure default typeless resolver, you can set by `MessagePackSerializer.Typeless.RegisterDefaultResolver`.
|
||||
|
||||
Performance
|
||||
---
|
||||
Benchmarks comparing to other serializers run on `Windows 10 Pro x64 Intel Core i7-6700K 4.00GHz, 32GB RAM`. Benchmark code is [here](https://github.com/neuecc/ZeroFormatter/tree/master/sandbox/PerformanceComparison) - and there [version info](https://github.com/neuecc/ZeroFormatter/blob/bc63cb925d/sandbox/PerformanceComparison/packages.config), ZeroFormatter and [FlatBuffers](https://google.github.io/flatbuffers/) has infinitely fast deserializer so ignore deserialize performance.
|
||||
|
@ -698,7 +727,7 @@ Extension Point(IFormatterResolver)
|
|||
| Resovler Name | Description |
|
||||
| --- | --- |
|
||||
| BuiltinResolver | Builtin primitive and standard classes resolver. It includes primitive(int, bool, string...) and there nullable, array and list. and some extra builtin types(Guid, Uri, BigInteger, etc...). |
|
||||
| StandardResolver | Composited resolver . It resolves in the following order `builtin -> attribute -> dynamic enum -> dynamic generic -> dynamic union -> dynamic object -> primitive object`. This is the default of MessagePackSerializer. |
|
||||
| StandardResolver | Composited resolver. It resolves in the following order `builtin -> attribute -> dynamic enum -> dynamic generic -> dynamic union -> dynamic object -> primitive object`. This is the default of MessagePackSerializer. |
|
||||
| ContractlessStandardResolver | Composited `StandardResolver`(except primitive) -> `DynamicContractlessObjectResolver` -> `DynamicObjectTypeFallbackResolver`. It enables contractless serialization. |
|
||||
| PrimitiveObjectResolver | MessagePack primitive object resolver. It is used fallback in `object` type and supports `bool`, `char`, `sbyte`, `byte`, `short`, `int`, `long`, `ushort`, `uint`, `ulong`, `float`, `double`, `DateTime`, `string`, `byte[]`, `ICollection`, `IDictionary`. |
|
||||
| DynamicObjectTypeFallbackResolver | It is used fallback in `object` type and resolve primitive object -> dynamic contractless object |
|
||||
|
@ -712,6 +741,8 @@ Extension Point(IFormatterResolver)
|
|||
| DynamicUnionResolver | Resolver of interface marked by UnionAttribute. It uses dynamic code generation to create dynamic formatter. |
|
||||
| DynamicObjectResolver | Resolver of class and struct maked by MessagePackObjectAttribute. It uses dynamic code generation to create dynamic formatter. |
|
||||
| DynamicContractlessObjectResolver | Resolver of all classes and structs. It does not needs MessagePackObjectAttribute and serialized key as string(same as marked [MessagePackObject(true)]). |
|
||||
| TypelessObjectResolver | Used for `object`, embed .NET type in binary by `ext(100)` format so no need to pass type in deserilization. |
|
||||
| TypelessContractlessStandardResolver | Composited resolver. It resolves in the following order `nativedatetime -> builtin -> attribute -> dynamic enum -> dynamic generic -> dynamic union -> dynamic object -> dynamiccontractless -> typeless`. This is the default of `MessagePackSerializer.Typeless` |
|
||||
|
||||
It is the only configuration point to assemble the resolver's priority. In most cases, it is sufficient to have one custom resolver globally. CompositeResolver will be its helper.
|
||||
|
||||
|
|
|
@ -259,22 +259,23 @@ namespace Sandbox
|
|||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var mc = new MyClass()
|
||||
{
|
||||
object mc = new Sandbox.MyClass()
|
||||
{
|
||||
Age = 10,
|
||||
FirstName = "hoge",
|
||||
LastName = "huga"
|
||||
};
|
||||
var dict = new ConcurrentDictionary<int, MyClass>();
|
||||
dict.TryAdd(1, mc);
|
||||
|
||||
var t = MessagePackSerializer.Typeless.Serialize(mc);
|
||||
// serialize to typeless
|
||||
var bin = MessagePackSerializer.Typeless.Serialize(mc);
|
||||
|
||||
// binary data is embeded type-assembly information.
|
||||
// ["Sandbox.MyClass, Sandbox",10,"hoge","huga"]
|
||||
Console.WriteLine(MessagePackSerializer.ToJson(bin));
|
||||
|
||||
var hoge = MessagePackSerializer.ToJson(t);
|
||||
Console.WriteLine(hoge);
|
||||
var nt = MessagePackSerializer.Typeless.Deserialize(t);
|
||||
// can deserialize to MyClass with typeless
|
||||
var objModel = MessagePackSerializer.Typeless.Deserialize(bin) as MyClass;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>TupleFormatter.tt</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Assets\Scripts\MessagePack\Formatters\TypelessFormatter.cs" />
|
||||
<Compile Include="Assets\Scripts\MessagePack\Formatters\ValueTupleFormatter.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
|
@ -155,6 +156,8 @@
|
|||
<Compile Include="Assets\Scripts\MessagePack\Resolvers\OldSpecResolver.cs" />
|
||||
<Compile Include="Assets\Scripts\MessagePack\Resolvers\PrimitiveObjectResolver.cs" />
|
||||
<Compile Include="Assets\Scripts\MessagePack\Resolvers\StandardResolver.cs" />
|
||||
<Compile Include="Assets\Scripts\MessagePack\Resolvers\TypelessContractlessStandardResolver.cs" />
|
||||
<Compile Include="Assets\Scripts\MessagePack\Resolvers\TypelessObjectResolver.cs" />
|
||||
<Compile Include="Assets\Scripts\MessagePack\Shims\Reflection.cs" />
|
||||
<Compile Include="Assets\Scripts\MessagePack\StringEncoding.cs" />
|
||||
<Compile Include="Assets\Scripts\MessagePack\Unity\Formatters.cs" />
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace MessagePack.Formatters
|
|||
/// </summary>
|
||||
public class TypelessFormatter : IMessagePackFormatter<object>
|
||||
{
|
||||
public const sbyte ExtensionTypeCode = 100;
|
||||
|
||||
static readonly Regex SubtractFullNameRegex = new Regex(@", Version=\d+.\d+.\d+.\d+, Culture=\w+, PublicKeyToken=\w+", RegexOptions.Compiled);
|
||||
|
||||
delegate int SerializeMethod(object dynamicContractlessFormatter, ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver);
|
||||
|
@ -144,7 +146,7 @@ namespace MessagePack.Formatters
|
|||
offset += 6; // mark will be written at the end, when size is known
|
||||
offset += MessagePackBinary.WriteString(ref bytes, offset, typeName);
|
||||
offset += formatterAndDelegate.Value(formatterAndDelegate.Key, ref bytes, offset, value, formatterResolver);
|
||||
MessagePackBinary.WriteExtensionFormatHeaderForceExt32Block(ref bytes, startOffset, (sbyte)ReservedMessagePackExtensionTypeCode.DynamicObjectWithTypeName, offset - startOffset - 6);
|
||||
MessagePackBinary.WriteExtensionFormatHeaderForceExt32Block(ref bytes, startOffset, (sbyte)TypelessFormatter.ExtensionTypeCode, offset - startOffset - 6);
|
||||
return offset - startOffset;
|
||||
}
|
||||
|
||||
|
@ -163,7 +165,7 @@ namespace MessagePack.Formatters
|
|||
case MessagePackType.Extension:
|
||||
{
|
||||
var ext = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize);
|
||||
if (ext.TypeCode == ReservedMessagePackExtensionTypeCode.DynamicObjectWithTypeName)
|
||||
if (ext.TypeCode == TypelessFormatter.ExtensionTypeCode)
|
||||
{
|
||||
// it has type name serialized
|
||||
offset += readSize;
|
||||
|
|
|
@ -18,6 +18,8 @@ namespace MessagePack.Internal
|
|||
return type.IsPublic;
|
||||
}
|
||||
|
||||
#if NETSTANDARD1_4
|
||||
|
||||
public static bool IsAnonymous(this System.Reflection.TypeInfo type)
|
||||
{
|
||||
return type.GetCustomAttribute<CompilerGeneratedAttribute>() != null
|
||||
|
@ -26,8 +28,6 @@ namespace MessagePack.Internal
|
|||
&& (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
|
||||
}
|
||||
|
||||
#if NETSTANDARD1_4
|
||||
|
||||
public static bool IsConstructedGenericType(this System.Reflection.TypeInfo type)
|
||||
{
|
||||
return type.AsType().IsConstructedGenericType;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MessagePack.Internal;
|
||||
using MessagePack.Formatters;
|
||||
using MessagePack.Internal;
|
||||
using MessagePack.LZ4;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
@ -165,7 +166,8 @@ namespace MessagePack
|
|||
builder.Append(dt.ToString("o", CultureInfo.InvariantCulture));
|
||||
builder.Append("\"");
|
||||
}
|
||||
else if (extHeader.TypeCode == ReservedMessagePackExtensionTypeCode.DynamicObjectWithTypeName)
|
||||
#if NETSTANDARD1_4
|
||||
else if (extHeader.TypeCode == TypelessFormatter.ExtensionTypeCode)
|
||||
{
|
||||
int startOffset = offset;
|
||||
// prepare type name token
|
||||
|
@ -196,6 +198,7 @@ namespace MessagePack
|
|||
}
|
||||
readSize = offset - startOffset;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
var ext = MessagePackBinary.ReadExtensionFormat(bytes, offset, out readSize);
|
||||
|
|
|
@ -184,7 +184,6 @@ namespace MessagePack
|
|||
public static class ReservedMessagePackExtensionTypeCode
|
||||
{
|
||||
public const sbyte DateTime = -1;
|
||||
public const sbyte DynamicObjectWithTypeName = 100;
|
||||
}
|
||||
|
||||
public static class MessagePackRange
|
||||
|
|
|
@ -239,7 +239,8 @@ namespace MessagePack
|
|||
builder.Append(dt.ToString("o", CultureInfo.InvariantCulture));
|
||||
builder.Append("\"");
|
||||
}
|
||||
else if (extHeader.TypeCode == ReservedMessagePackExtensionTypeCode.DynamicObjectWithTypeName)
|
||||
#if NETSTANDARD1_4
|
||||
else if (extHeader.TypeCode == TypelessFormatter.ExtensionTypeCode)
|
||||
{
|
||||
int startOffset = offset;
|
||||
// prepare type name token
|
||||
|
@ -270,6 +271,7 @@ namespace MessagePack
|
|||
}
|
||||
readSize = offset - startOffset;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
var ext = MessagePackBinary.ReadExtensionFormat(bytes, offset, out readSize);
|
||||
|
|
Загрузка…
Ссылка в новой задаче