public PolymorphicComplexBuilder(Type type, SerializerState state) { _typeDescriptionsByHashCode = new AdaptiveHashtable <TypeDescriptionWithIndex>(); var typeDescriptions = new Dictionary <int, TypeDescriptionWithIndex>(); foreach (var description in state.GetDescriptionsForDerivedTypes(type)) { _typeDescriptionsByHashCode.AddValue( (uint)RuntimeHelpers.GetHashCode(description.Type), new TypeDescriptionWithIndex { Description = description }); if (!typeDescriptions.ContainsKey(description.Type.GetHashCode())) { typeDescriptions.Add(description.Type.GetHashCode(), new TypeDescriptionWithIndex { Description = description }); } } _typeDescriptionsByIndex = new TypeDescription[typeDescriptions.Count]; var index = (byte)0; foreach (var item in typeDescriptions) { item.Value.Index = index; var val = _typeDescriptionsByHashCode.TryGetValue((uint)RuntimeHelpers.GetHashCode(item.Value.Description.Type)); Debug.Assert(val != null, "Type should exist in the type descriptions hash"); val.Index = index; _typeDescriptionsByIndex[index++] = item.Value.Description; } }
internal static MemberSerializerBuilder GetBuilder(Type type, TypeDescription nestedTypeDescription, SerializerState state) { var serializerBuilder = default(MemberSerializerBuilder); if (type.IsBuiltInType()) { var nullableUnderlyingType = Nullable.GetUnderlyingType(type); if (nullableUnderlyingType != null) { if (nullableUnderlyingType.IsBuiltInType()) { serializerBuilder = CreateBuilder(typeof(PrimitiveNullableBuilder <>), nullableUnderlyingType, nullableUnderlyingType); } else { serializerBuilder = CreateBuilder(typeof(ComplexNullableBuilder <>), nullableUnderlyingType, nullableUnderlyingType, state); } } else { if (PrimitiveBuilders.TryGetValue(type, out serializerBuilder)) { return(serializerBuilder); } type.TypeNotSupported(type); } } else { if (type.GetTypeInfo().IsEnum) { serializerBuilder = CreateBuilder(typeof(EnumBuilder <>), type, type, Enum.GetUnderlyingType(type)); } else if (type.IsDictionaryType()) { var dictTypes = type.GetDictionaryArguments(); Debug.Assert(dictTypes != null, "Dictionary generic types can't be null for a dictionary"); Debug.Assert(state != null, "State can't be null"); serializerBuilder = CreateBuilder( typeof(DictionaryBuilder <, ,>), new[] { type, dictTypes.Item1, dictTypes.Item2 }, type, dictTypes.Item1, dictTypes.Item2, GetTypeDescription(dictTypes.Item1, state), GetTypeDescription(dictTypes.Item2, state), state); } else if (type.IsEnumerableType()) { var baseElementType = type.GetEnumerableArgument(); Debug.Assert(baseElementType != null, "Element generic type can't be null for an enumerable"); Debug.Assert(state != null, "State can't be null"); serializerBuilder = CreateBuilder( typeof(EnumerableBuilder <,>), new[] { type, baseElementType }, type, baseElementType, GetTypeDescription(baseElementType, state), state); } else if (type.GetTypeInfo().IsInterface || type.GetTypeInfo().IsAbstract) { var derivedTypes = state.GetDescriptionsForDerivedTypes(type); if (!derivedTypes.Any()) { type.NoImplementationsFound(type); } if (derivedTypes.Count() > 1) { serializerBuilder = CreateBuilder(typeof(PolymorphicComplexBuilder <>), type, type, state); } else { serializerBuilder = CreateBuilder(typeof(ComplexBuilder <>), derivedTypes.First().Type, derivedTypes.First()); serializerBuilder = WrapWithCheckNullBuilder(type, serializerBuilder); } } else if (nestedTypeDescription != null) { var derivedTypes = state.GetDescriptionsForDerivedTypes(type); if (derivedTypes.Count() > 1) { serializerBuilder = CreateBuilder(typeof(PolymorphicComplexBuilder <>), type, type, state); } else { serializerBuilder = CreateBuilder(typeof(ComplexBuilder <>), type, nestedTypeDescription); if (!type.GetTypeInfo().IsValueType) { serializerBuilder = WrapWithCheckNullBuilder(type, serializerBuilder); } } } else { type.TypeNotSupported(type); } } return(serializerBuilder); }