/// <summary>
        /// Creates a <see cref="WithCSharpExpression"/> that represents a with expression.
        /// </summary>
        /// <param name="object">The expression representing the object to clone and mutate.</param>
        /// <param name="clone">The method used to clone the object.</param>
        /// <param name="initializers">The initializers used to mutate the cloned object.</param>
        /// <returns>The created <see cref="WithCSharpExpression"/>.</returns>
        public static WithCSharpExpression With(Expression @object, MethodInfo clone, IEnumerable <MemberInitializer> initializers)
        {
            RequiresNotNull(@object, nameof(@object));
            RequiresNotNull(initializers, nameof(initializers));

            var initializersCollection = initializers.ToReadOnly();

            ValidateWithReceiverAndInitializers(@object, initializersCollection, requiresCanAssign: true);

            if (@object.Type.IsValueType)
            {
                if (clone != null)
                {
                    throw Error.WithExpressionCannotHaveCloneForValueType(@object.Type);
                }
            }
            else
            {
                clone ??= @object.Type.GetNonGenericMethod("Clone", BindingFlags.Public | BindingFlags.Instance, Type.EmptyTypes);

                if (clone == null)
                {
                    throw Error.WithExpressionShouldHaveClone(@object.Type);
                }

                ValidateMethodInfo(clone);

                if (clone.IsStatic)
                {
                    throw Error.CloneMethodMustNotBeStatic(clone.Name);
                }

                if (!clone.DeclaringType.IsAssignableFrom(@object.Type))
                {
                    throw LinqError.NotAMemberOfType(clone.Name, @object.Type);
                }

                if (clone.GetParametersCached().Length != 0)
                {
                    throw Error.CloneMethodShouldHaveNoParameters(clone.Name);
                }

                if (!HasReferenceConversion(clone.ReturnType, @object.Type))
                {
                    throw Error.CloneMethodShouldReturnCompatibleType(clone.Name, @object.Type);
                }
            }

            return(new WithCSharpExpression(@object, initializersCollection, clone, members: null));
        }