/// <summary>
        /// Creates a new structural type that's initially mutable.
        /// </summary>
        /// <param name="hasValueEqualitySemantics">true if the structural type has value equality semantics, false otherwise.</param>
        /// <param name="kind">The kind of structural type.</param>
        /// <param name="capacity">The number of properties expected.</param>
        /// <returns>A new structural type that's initially mutable.</returns>
        public static StructuralTypeSlimReference Create(bool hasValueEqualitySemantics, StructuralTypeSlimKind kind, int capacity)
        {
            if (capacity < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(capacity));
            }

            return(kind switch
            {
                StructuralTypeSlimKind.Anonymous => AnonymousStructuralTypeSlimReference.Create(hasValueEqualitySemantics, capacity),
                StructuralTypeSlimKind.Record => RecordStructuralTypeSlimReference.Create(hasValueEqualitySemantics, capacity),
                _ => throw new NotSupportedException(),
            });
        // PERF: Consider creating specialized layouts for this type. Note this is not too pressing
        //       because the Structural factory method is rarely used. Instead, these types are often
        //       built using the StructuralTypeSlimReference.Create factory methods using a builder
        //       pattern.

        #region Constructors

        /// <summary>
        /// Creates a new structural type representation object.
        /// </summary>
        /// <param name="properties">The set of properties for the structural type.</param>
        /// <param name="hasValueEqualitySemantics">true if type uses value equality semantics, false otherwise.</param>
        /// <param name="kind">The kind of structural type to create/serialize.</param>
        public ReadOnlyStructuralTypeSlim(ReadOnlyCollection <PropertyInfoSlim> properties, bool hasValueEqualitySemantics, StructuralTypeSlimKind kind)
        {
            Properties                = properties;
            StructuralKind            = kind;
            HasValueEqualitySemantics = hasValueEqualitySemantics;
        }
 /// <summary>
 /// Creates a new structural type that's initially mutable.
 /// </summary>
 /// <param name="hasValueEqualitySemantics">true if the structural type has value equality semantics, false otherwise.</param>
 /// <param name="kind">The kind of structural type.</param>
 /// <returns>A new structural type that's initially mutable.</returns>
 public static StructuralTypeSlimReference Create(bool hasValueEqualitySemantics, StructuralTypeSlimKind kind) => Create(hasValueEqualitySemantics, kind, capacity: 0);
        /// <summary>
        /// Creates a new lightweight representation of a structural type with the specified properties.
        /// </summary>
        /// <param name="properties">The properties of the structural type.</param>
        /// <param name="hasValueEqualitySemantics">true if the structural type has value equality semantics, false otherwise.</param>
        /// <param name="kind">The kind of structural type.</param>
        /// <returns>A new lightweight representation of a structural type with the specified properties.</returns>
        public static StructuralTypeSlim Structural(ReadOnlyCollection <PropertyInfoSlim> properties, bool hasValueEqualitySemantics, StructuralTypeSlimKind kind)
        {
            RequireNotNull(properties, nameof(properties));

            return(new ReadOnlyStructuralTypeSlim(properties, hasValueEqualitySemantics, kind));
        }