/// <summary>
 /// Gets the serialization template for the specified type.
 /// </summary>
 /// <param name="type">The type to look up.</param>
 /// <returns>The template for that type.</returns>
 public static FastSerializationTemplate GetFastSerializationTemplate(Type type)
 {
     if (type == null)
     {
         throw new ArgumentNullException(nameof(type),
                                         "Invalid type encountered when serializing");
     }
     if (!SERIALIZATION_TEMPLATES_ACTIVE.TryGetValue(type, out FastSerializationTemplate
                                                     template))
     {
         if (!SERIALIZATION_TEMPLATES.TryGetValue(type, out FastSerializationTemplate
                                                  cached))
         {
             cached = new FastSerializationTemplate(type);
             SERIALIZATION_TEMPLATES.Add(type, cached);
         }
         SERIALIZATION_TEMPLATES_ACTIVE.Add(type, template = cached);
     }
     return(template);
 }
        public FastDeserializationMapping(DeserializationTemplate inTemplate,
                                          FastSerializationTemplate outTemplate)
        {
            targetType = outTemplate.targetType;
            template   = inTemplate;
            members    = new List <FastDeserializationInfo>(16);
            // Dictionaries look up faster than lists!
            var fields     = outTemplate.serializableFields;
            var properties = outTemplate.serializableProperties;

            foreach (var memberInfo in inTemplate.serializedMembers)
            {
                FastDeserializationInfo dinfo;
                string name     = memberInfo.name;
                var    typeInfo = memberInfo.typeInfo;
                if (fields.TryGetValue(name, out DeserializationFieldInfo outField) &&
                    typeInfo.Equals(outField.targetType))
                {
                    dinfo = outField;
                }
                else if (properties.TryGetValue(name, out DeserializationPropertyInfo
                                                outProperty) && typeInfo.Equals(outProperty.targetType))
                {
                    dinfo = outProperty;
                }
                else
                {
                    dinfo = new FastDeserializationInfo(false, typeInfo);
                }
                if (typeInfo.type == null)
                {
                    Debug.LogWarningFormat("Tried to deserialize field '{0}' on type {1} but it no longer exists",
                                           name, inTemplate.typeName);
                }
                members.Add(dinfo);
            }
        }