static Formatter() { object formatter = null; var t = typeof(T); var ti = t.GetTypeInfo(); try { // Primitive if (t == typeof(Int16)) { formatter = new Int16Formatter(); } else if (t == typeof(Int32)) { formatter = new Int32Formatter(); } else if (t == typeof(Int64)) { formatter = new Int64Formatter(); } else if (t == typeof(UInt16)) { formatter = new UInt16Formatter(); } else if (t == typeof(UInt32)) { formatter = new UInt32Formatter(); } else if (t == typeof(UInt64)) { formatter = new UInt64Formatter(); } else if (t == typeof(Single)) { formatter = new SingleFormatter(); } else if (t == typeof(Double)) { formatter = new DoubleFormatter(); } else if (t == typeof(bool)) { formatter = new BooleanFormatter(); } else if (t == typeof(byte)) { formatter = new ByteFormatter(); } else if (t == typeof(sbyte)) { formatter = new SByteFormatter(); } else if (t == typeof(decimal)) { formatter = new DecimalFormatter(); } else if (t == typeof(TimeSpan)) { formatter = new TimeSpanFormatter(); } else if (t == typeof(DateTime)) { formatter = new DateTimeFormatter(); } else if (t == typeof(DateTimeOffset)) { formatter = new DateTimeOffsetFormatter(); } // Nulllable else if (t == typeof(Nullable <Int16>)) { formatter = new NullableInt16Formatter(); } else if (t == typeof(Nullable <Int32>)) { formatter = new NullableInt32Formatter(); } else if (t == typeof(Nullable <Int64>)) { formatter = new NullableInt64Formatter(); } else if (t == typeof(Nullable <UInt16>)) { formatter = new NullableUInt16Formatter(); } else if (t == typeof(Nullable <UInt32>)) { formatter = new NullableUInt32Formatter(); } else if (t == typeof(Nullable <UInt64>)) { formatter = new NullableUInt64Formatter(); } else if (t == typeof(Nullable <Single>)) { formatter = new NullableSingleFormatter(); } else if (t == typeof(Nullable <Double>)) { formatter = new NullableDoubleFormatter(); } else if (t == typeof(Nullable <bool>)) { formatter = new NullableBooleanFormatter(); } else if (t == typeof(Nullable <byte>)) { formatter = new NullableByteFormatter(); } else if (t == typeof(Nullable <sbyte>)) { formatter = new NullableSByteFormatter(); } else if (t == typeof(Nullable <decimal>)) { formatter = new NullableDecimalFormatter(); } else if (t == typeof(Nullable <TimeSpan>)) { formatter = new NullableTimeSpanFormatter(); } else if (t == typeof(Nullable <DateTime>)) { formatter = new NullableDateTimeFormatter(); } else if (t == typeof(Nullable <DateTimeOffset>)) { formatter = new NullableDateTimeOffsetFormatter(); } // Others else if (t == typeof(String)) { formatter = new StringFormatter(); } else if (t == typeof(Char)) { formatter = new CharFormatter(); } else if (t == typeof(Char?)) { formatter = new NullableCharFormatter(); } else if (t == typeof(byte[])) { formatter = new ByteArrayFormatter(); } else if (t == typeof(IList <int>)) // known generic formatter... { formatter = new ListFormatter <int>(); } #if !UNITY else if (ti.IsGenericType && t.GetGenericTypeDefinition() == typeof(IList <>)) { var formatterType = typeof(ListFormatter <>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (ti.IsGenericType && t.GetGenericTypeDefinition() == typeof(IReadOnlyList <>)) { var formatterType = typeof(ReadOnlyListFormatter <>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (ti.IsEnum) { var underlyingType = Enum.GetUnderlyingType(t); switch (Type.GetTypeCode(underlyingType)) { case TypeCode.SByte: formatter = new SByteEnumFormatter <T>(); break; case TypeCode.Byte: formatter = new ByteEnumFormatter <T>(); break; case TypeCode.Int16: formatter = new Int16EnumFormatter <T>(); break; case TypeCode.UInt16: formatter = new UInt16EnumFormatter <T>(); break; case TypeCode.Int32: formatter = new Int32EnumFormatter <T>(); break; case TypeCode.UInt32: formatter = new UInt32EnumFormatter <T>(); break; case TypeCode.Int64: formatter = new Int64EnumFormatter <T>(); break; case TypeCode.UInt64: formatter = new UInt64EnumFormatter <T>(); break; default: throw new Exception(); } } else if (ti.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>) && ti.GetGenericArguments()[0].GetTypeInfo().IsEnum) { var underlyingType = Enum.GetUnderlyingType(ti.GetGenericArguments()[0]); switch (Type.GetTypeCode(underlyingType)) { case TypeCode.SByte: { var formatterType = typeof(NullableSByteEnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.Byte: { var formatterType = typeof(NullableByteEnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.Int16: { var formatterType = typeof(NullableInt16EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.UInt16: { var formatterType = typeof(NullableUInt16EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.Int32: { var formatterType = typeof(NullableInt32EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.UInt32: { var formatterType = typeof(NullableUInt32EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.Int64: { var formatterType = typeof(NullableInt64EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.UInt64: { var formatterType = typeof(NullableUInt64EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; default: throw new Exception(); } } else if (ti.IsGenericType) { if (t.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { var formatterType = typeof(DictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ILazyDictionary <,>)) { var formatterType = typeof(LazyDictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary <,>)) { var formatterType = typeof(ReadOnlyDictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ILazyReadOnlyDictionary <,>)) { var formatterType = typeof(LazyReadOnlyDictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(DictionaryEntry <,>)) { var formatterType = typeof(DictionaryEntryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ILookup <,>)) { var formatterType = typeof(LookupFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ILazyLookup <,>)) { var formatterType = typeof(LazyLookupFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(GroupingSegment <,>)) { var formatterType = typeof(GroupingSegmentFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (ti.GetInterfaces().Any(x => x == typeof(IKeyTuple))) { Type tupleFormatterType = null; switch (ti.GetGenericArguments().Length) { case 1: tupleFormatterType = typeof(KeyTupleFormatter <>); break; case 2: tupleFormatterType = typeof(KeyTupleFormatter <,>); break; case 3: tupleFormatterType = typeof(KeyTupleFormatter <, ,>); break; case 4: tupleFormatterType = typeof(KeyTupleFormatter <, , ,>); break; case 5: tupleFormatterType = typeof(KeyTupleFormatter <, , , ,>); break; case 6: tupleFormatterType = typeof(KeyTupleFormatter <, , , , ,>); break; case 7: tupleFormatterType = typeof(KeyTupleFormatter <, , , , , ,>); break; case 8: tupleFormatterType = typeof(KeyTupleFormatter <, , , , , , ,>); break; default: break; } var formatterType = tupleFormatterType.MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { throw new InvalidOperationException("Dictionary does not support in ZeroFormatter because Dictionary have to deserialize all objects. You can use IDictionary<TK, TV> instead of Dictionary."); } // custom nullable struct else if (t.GetGenericTypeDefinition() == typeof(Nullable <>) && ti.GetGenericArguments()[0].GetTypeInfo().IsValueType) { formatter = DynamicStructFormatter.Create <T>(); } } else if (t.IsArray) { throw new InvalidOperationException("Array does not support in ZeroFormatter(except byte[]) because Array have to deserialize all objects. You can use IList<T> instead of T[]."); } else if (ti.GetCustomAttributes(typeof(ZeroFormattableAttribute), true).FirstOrDefault() != null) { if (ti.IsValueType) { formatter = DynamicStructFormatter.Create <T>(); } else { formatter = DynamicObjectFormatter.Create <T>(); } } #endif } catch (InvalidOperationException ex) { formatter = new ErrorFormatter <T>(ex); } catch (Exception ex) { formatter = new ErrorFormatter <T>(ex); } // resolver if (formatter == null || formatter is ErrorFormatter <T> ) { try { var resolvedFormatter = Formatter.ResolveFormatter <T>(); if (resolvedFormatter != null) { formatter = (Formatter <T>)resolvedFormatter; } else if (formatter == null) { formatter = new ErrorFormatter <T>(); } } catch (Exception ex) { formatter = new ErrorFormatter <T>(ex); } } Default = (Formatter <T>)formatter; }
static Formatter() { object formatter = null; var t = typeof(T); var ti = t.GetTypeInfo(); try { // Primitive if (t == typeof(Int16)) { formatter = new Int16Formatter(); } else if (t == typeof(Int32)) { formatter = new Int32Formatter(); } else if (t == typeof(Int64)) { formatter = new Int64Formatter(); } else if (t == typeof(UInt16)) { formatter = new UInt16Formatter(); } else if (t == typeof(UInt32)) { formatter = new UInt32Formatter(); } else if (t == typeof(UInt64)) { formatter = new UInt64Formatter(); } else if (t == typeof(Single)) { formatter = new SingleFormatter(); } else if (t == typeof(Double)) { formatter = new DoubleFormatter(); } else if (t == typeof(bool)) { formatter = new BooleanFormatter(); } else if (t == typeof(byte)) { formatter = new ByteFormatter(); } else if (t == typeof(sbyte)) { formatter = new SByteFormatter(); } else if (t == typeof(decimal)) { formatter = new DecimalFormatter(); } else if (t == typeof(TimeSpan)) { formatter = new TimeSpanFormatter(); } else if (t == typeof(DateTime)) { formatter = new DateTimeFormatter(); } else if (t == typeof(DateTimeOffset)) { formatter = new DateTimeOffsetFormatter(); } else if (t == typeof(Guid)) { formatter = new GuidFormatter(); } // Nulllable else if (t == typeof(Nullable <Int16>)) { formatter = new NullableInt16Formatter(); } else if (t == typeof(Nullable <Int32>)) { formatter = new NullableInt32Formatter(); } else if (t == typeof(Nullable <Int64>)) { formatter = new NullableInt64Formatter(); } else if (t == typeof(Nullable <UInt16>)) { formatter = new NullableUInt16Formatter(); } else if (t == typeof(Nullable <UInt32>)) { formatter = new NullableUInt32Formatter(); } else if (t == typeof(Nullable <UInt64>)) { formatter = new NullableUInt64Formatter(); } else if (t == typeof(Nullable <Single>)) { formatter = new NullableSingleFormatter(); } else if (t == typeof(Nullable <Double>)) { formatter = new NullableDoubleFormatter(); } else if (t == typeof(Nullable <bool>)) { formatter = new NullableBooleanFormatter(); } else if (t == typeof(Nullable <byte>)) { formatter = new NullableByteFormatter(); } else if (t == typeof(Nullable <sbyte>)) { formatter = new NullableSByteFormatter(); } else if (t == typeof(Nullable <decimal>)) { formatter = new NullableDecimalFormatter(); } else if (t == typeof(Nullable <TimeSpan>)) { formatter = new NullableTimeSpanFormatter(); } else if (t == typeof(Nullable <DateTime>)) { formatter = new NullableDateTimeFormatter(); } else if (t == typeof(Nullable <DateTimeOffset>)) { formatter = new NullableDateTimeOffsetFormatter(); } else if (t == typeof(Guid?)) { formatter = new NullableGuidFormatter(); } // Others else if (t == typeof(String)) { formatter = new NullableStringFormatter(); } else if (t == typeof(Char)) { formatter = new CharFormatter(); } else if (t == typeof(Char?)) { formatter = new NullableCharFormatter(); } else if (t == typeof(IList <int>)) // known generic formatter... { formatter = new ListFormatter <int>(); } else if (t.IsArray) { var elementType = t.GetElementType(); switch (Type.GetTypeCode(elementType)) { case TypeCode.Boolean: formatter = new BooleanArrayFormatter(); break; case TypeCode.Char: formatter = new CharArrayFormatter(); break; case TypeCode.SByte: formatter = new SByteArrayFormatter(); break; case TypeCode.Byte: formatter = new ByteArrayFormatter(); break; case TypeCode.Int16: formatter = new Int16ArrayFormatter(); break; case TypeCode.UInt16: formatter = new UInt16ArrayFormatter(); break; case TypeCode.Int32: formatter = new Int32ArrayFormatter(); break; case TypeCode.UInt32: formatter = new UInt32ArrayFormatter(); break; case TypeCode.Int64: formatter = new Int64ArrayFormatter(); break; case TypeCode.UInt64: formatter = new UInt64ArrayFormatter(); break; case TypeCode.Single: formatter = new SingleArrayFormatter(); break; case TypeCode.Double: formatter = new DoubleArrayFormatter(); break; default: #if !UNITY var formatterType = typeof(ArrayFormatter <>).MakeGenericType(elementType); formatter = Activator.CreateInstance(formatterType); #endif break; } } #if !UNITY else if (ti.IsGenericType && t.GetGenericTypeDefinition() == typeof(IList <>)) { var formatterType = typeof(ListFormatter <>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (ti.IsGenericType && t.GetGenericTypeDefinition() == typeof(IReadOnlyList <>)) { var formatterType = typeof(ReadOnlyListFormatter <>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (ti.IsEnum) { var underlyingType = Enum.GetUnderlyingType(t); switch (Type.GetTypeCode(underlyingType)) { case TypeCode.SByte: formatter = new SByteEnumFormatter <T>(); break; case TypeCode.Byte: formatter = new ByteEnumFormatter <T>(); break; case TypeCode.Int16: formatter = new Int16EnumFormatter <T>(); break; case TypeCode.UInt16: formatter = new UInt16EnumFormatter <T>(); break; case TypeCode.Int32: formatter = new Int32EnumFormatter <T>(); break; case TypeCode.UInt32: formatter = new UInt32EnumFormatter <T>(); break; case TypeCode.Int64: formatter = new Int64EnumFormatter <T>(); break; case TypeCode.UInt64: formatter = new UInt64EnumFormatter <T>(); break; default: throw new Exception(); } } else if (ti.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>) && ti.GetGenericArguments()[0].GetTypeInfo().IsEnum) { var underlyingType = Enum.GetUnderlyingType(ti.GetGenericArguments()[0]); switch (Type.GetTypeCode(underlyingType)) { case TypeCode.SByte: { var formatterType = typeof(NullableSByteEnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.Byte: { var formatterType = typeof(NullableByteEnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.Int16: { var formatterType = typeof(NullableInt16EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.UInt16: { var formatterType = typeof(NullableUInt16EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.Int32: { var formatterType = typeof(NullableInt32EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.UInt32: { var formatterType = typeof(NullableUInt32EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.Int64: { var formatterType = typeof(NullableInt64EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; case TypeCode.UInt64: { var formatterType = typeof(NullableUInt64EnumFormatter <>).MakeGenericType(ti.GetGenericArguments()[0]); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } break; default: throw new Exception(); } } else if (ti.IsGenericType) { if (t.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { var formatterType = typeof(InterfaceDictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ILazyDictionary <,>)) { var formatterType = typeof(LazyDictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary <,>)) { var formatterType = typeof(InterfaceReadOnlyDictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ILazyReadOnlyDictionary <,>)) { var formatterType = typeof(LazyReadOnlyDictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(DictionaryEntry <,>)) { var formatterType = typeof(DictionaryEntryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ILookup <,>)) { var formatterType = typeof(LookupFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ILazyLookup <,>)) { var formatterType = typeof(LazyLookupFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(GroupingSegment <,>)) { var formatterType = typeof(GroupingSegmentFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (ti.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)) { var formatterType = typeof(KeyValuePairFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { var formatterType = typeof(DictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ReadOnlyDictionary <,>)) { var formatterType = typeof(ReadOnlyDictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ReadOnlyCollection <>)) { var formatterType = typeof(ReadOnlyCollectionFormatter <>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ICollection <>)) { var formatterType = typeof(InterfaceCollectionFormatter <>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { var formatterType = typeof(InterfaceEnumerableFormatter <>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(ISet <>)) { var formatterType = typeof(InterfaceSetFormatter <>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(IReadOnlyCollection <>)) { var formatterType = typeof(InterfaceReadOnlyCollectionFormatter <>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (t.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary <,>)) { var formatterType = typeof(InterfaceReadOnlyDictionaryFormatter <,>).MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (ti.FullName.StartsWith("System.Tuple")) { Type tupleFormatterType = null; switch (ti.GetGenericArguments().Length) { case 1: tupleFormatterType = typeof(TupleFormatter <>); break; case 2: tupleFormatterType = typeof(TupleFormatter <,>); break; case 3: tupleFormatterType = typeof(TupleFormatter <, ,>); break; case 4: tupleFormatterType = typeof(TupleFormatter <, , ,>); break; case 5: tupleFormatterType = typeof(TupleFormatter <, , , ,>); break; case 6: tupleFormatterType = typeof(TupleFormatter <, , , , ,>); break; case 7: tupleFormatterType = typeof(TupleFormatter <, , , , , ,>); break; case 8: tupleFormatterType = typeof(TupleFormatter <, , , , , , ,>); break; default: break; } var formatterType = tupleFormatterType.MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (ti.GetInterfaces().Any(x => x == typeof(IKeyTuple))) { Type tupleFormatterType = null; switch (ti.GetGenericArguments().Length) { case 1: tupleFormatterType = typeof(KeyTupleFormatter <>); break; case 2: tupleFormatterType = typeof(KeyTupleFormatter <,>); break; case 3: tupleFormatterType = typeof(KeyTupleFormatter <, ,>); break; case 4: tupleFormatterType = typeof(KeyTupleFormatter <, , ,>); break; case 5: tupleFormatterType = typeof(KeyTupleFormatter <, , , ,>); break; case 6: tupleFormatterType = typeof(KeyTupleFormatter <, , , , ,>); break; case 7: tupleFormatterType = typeof(KeyTupleFormatter <, , , , , ,>); break; case 8: tupleFormatterType = typeof(KeyTupleFormatter <, , , , , , ,>); break; default: break; } var formatterType = tupleFormatterType.MakeGenericType(ti.GetGenericArguments()); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } else if (ti.GetInterfaces().Any(x => { var iti = x.GetTypeInfo(); if (iti.IsGenericType && iti.GetGenericTypeDefinition() == typeof(ICollection <>)) { return(true); } return(false); })) { var formatterType = typeof(CollectionFormatter <,>).MakeGenericType(ti.GetGenericArguments()[0], t); formatter = (Formatter <T>)Activator.CreateInstance(formatterType); } // custom nullable struct else if (t.GetGenericTypeDefinition() == typeof(Nullable <>) && ti.GetGenericArguments()[0].GetTypeInfo().IsValueType) { formatter = DynamicStructFormatter.Create <T>(); } } else if (ti.GetCustomAttributes(typeof(UnionAttribute), false).FirstOrDefault() != null) { formatter = DynamicUnionFormatter.Create <T>(); } else if (ti.GetCustomAttributes(typeof(ZeroFormattableAttribute), true).FirstOrDefault() != null) { if (ti.IsValueType) { formatter = DynamicStructFormatter.Create <T>(); } else { formatter = DynamicFormatter.Create <T>(); } } #endif } catch (InvalidOperationException ex) { formatter = new ErrorFormatter <T>(ex); } catch (Exception ex) { formatter = new ErrorFormatter <T>(ex); } // resolver if (formatter == null || formatter is ErrorFormatter <T> ) { try { var resolvedFormatter = Formatter.ResolveFormatter <T>(); if (resolvedFormatter != null) { formatter = (Formatter <T>)resolvedFormatter; } else if (formatter == null) { formatter = new ErrorFormatter <T>(); } } catch (Exception ex) { formatter = new ErrorFormatter <T>(ex); } } Default = (Formatter <T>)formatter; }