protected void WriteObject()

in src/Microsoft.VisualStudio.Composition/Configuration/SerializationContextBase.cs [877:1012]


        protected void WriteObject(object? value)
        {
            if (value == null)
            {
                using (this.Trace("Object"))
                {
                    this.Write(ObjectType.Null);
                }
            }
            else
            {
                Type valueType = value.GetType();
                using (this.Trace("Object"))
                {
                    if (valueType.IsArray)
                    {
                        Array array = (Array)value;
                        this.Write(ObjectType.Array);
                        TypeRef? elementTypeRef = TypeRef.Get(valueType.GetElementType(), this.Resolver);
                        this.Write(elementTypeRef);
                        this.Write(array, this.WriteObject);
                    }
                    else if (valueType == typeof(bool))
                    {
                        this.Write((bool)value ? ObjectType.BoolTrue : ObjectType.BoolFalse);
                    }
                    else if (valueType == typeof(string))
                    {
                        this.Write(ObjectType.String);
                        this.Write((string)value);
                    }
                    else if (valueType == typeof(long))
                    {
                        this.Write(ObjectType.Int64);
                        this.writer.Write((long)value);
                    }
                    else if (valueType == typeof(ulong))
                    {
                        this.Write(ObjectType.UInt64);
                        this.writer.Write((ulong)value);
                    }
                    else if (valueType == typeof(int))
                    {
                        this.Write(ObjectType.Int32);
                        this.writer.Write((int)value);
                    }
                    else if (valueType == typeof(uint))
                    {
                        this.Write(ObjectType.UInt32);
                        this.writer.Write((uint)value);
                    }
                    else if (valueType == typeof(short))
                    {
                        this.Write(ObjectType.Int16);
                        this.writer.Write((short)value);
                    }
                    else if (valueType == typeof(ushort))
                    {
                        this.Write(ObjectType.UInt16);
                        this.writer.Write((ushort)value);
                    }
                    else if (valueType == typeof(byte))
                    {
                        this.Write(ObjectType.Byte);
                        this.writer.Write((byte)value);
                    }
                    else if (valueType == typeof(sbyte))
                    {
                        this.Write(ObjectType.SByte);
                        this.writer.Write((sbyte)value);
                    }
                    else if (valueType == typeof(float))
                    {
                        this.Write(ObjectType.Single);
                        this.writer.Write((float)value);
                    }
                    else if (valueType == typeof(double))
                    {
                        this.Write(ObjectType.Double);
                        this.writer.Write((double)value);
                    }
                    else if (valueType == typeof(char))
                    {
                        this.Write(ObjectType.Char);
                        this.writer.Write((char)value);
                    }
                    else if (valueType == typeof(Guid))
                    {
                        this.Write(ObjectType.Guid);
                        this.Write((Guid)value);
                    }
                    else if (valueType == typeof(CreationPolicy)) // TODO: how do we handle arbitrary value types?
                    {
                        this.Write(ObjectType.CreationPolicy);
                        this.writer.Write((byte)(CreationPolicy)value);
                    }
                    else if (typeof(Type).GetTypeInfo().IsAssignableFrom(valueType))
                    {
                        this.Write(ObjectType.Type);
                        this.Write(TypeRef.Get((Type)value, this.Resolver));
                    }
                    else if (typeof(TypeRef) == valueType)
                    {
                        this.Write(ObjectType.TypeRef);
                        this.Write((TypeRef)value);
                    }
                    else if (typeof(LazyMetadataWrapper.Enum32Substitution) == valueType)
                    {
                        var substValue = (LazyMetadataWrapper.Enum32Substitution)value;
                        this.Write(ObjectType.Enum32Substitution);
                        this.Write(substValue.EnumType);
                        this.writer.Write(substValue.RawValue);
                    }
                    else if (typeof(LazyMetadataWrapper.TypeSubstitution) == valueType)
                    {
                        var substValue = (LazyMetadataWrapper.TypeSubstitution)value;
                        this.Write(ObjectType.TypeSubstitution);
                        this.Write(substValue.TypeRef);
                    }
                    else if (typeof(LazyMetadataWrapper.TypeArraySubstitution) == valueType)
                    {
                        var substValue = (LazyMetadataWrapper.TypeArraySubstitution)value;
                        this.Write(ObjectType.TypeArraySubstitution);
                        this.Write(substValue.TypeRefArray, this.Write);
                    }
                    else
                    {
                        Debug.WriteLine("Falling back to binary formatter for value of type: {0}", valueType);
                        this.Write(ObjectType.BinaryFormattedObject);
                        var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                        this.writer.Flush();
                        formatter.Serialize(this.writer.BaseStream, value);
                    }
                }
            }
        }