Repository: PowerShell/PowerShell
File: src/System.Management.Automation/engine/runtime/Binding/Binders.cs (C#)

Code before:
                    {
                        var arg = args[i].CastOrConvertMethodArgument(
                            parameterType,
                            paramName,
                            mi.Name,
                            allowCastingToByRefLikeType: false,
                            temps,
                            initTemps);
                        argExprs[i] = arg;
                    }
                }
                else if (i >= args.Length)
                {
                    Diagnostics.Assert(parameters[i].IsOptional,
                        "if there are too few arguments, FindBestMethod should only succeed if parameters are optional");
                    var argValue = parameters[i].DefaultValue;
                    if (argValue == null)
                    {
                        argExprs[i] = Expression.Default(parameterType);
                    }
                    else
                    {
                        // We don't specify the parameter type in the constant expression. Normally the default
                        // argument's type should match the parameter type, but sometimes it won't, e.g. with COM,
                        // the default can be System.Reflection.Missing.Value and this value is handled specially.
                        argExprs[i] = Expression.Constant(argValue);
                    }
                }
                else
                {
                    if (parameterType.IsByRef)
                    {
                        if (args[i].Value is not PSReference)
                        {
                            return Compiler.CreateThrow(typeof(object), typeof(MethodException),
                                     new[] { typeof(string), typeof(Exception), typeof(string), typeof(object[]) },
                                     "NonRefArgumentToRefParameterMsg", null, ExtendedTypeSystem.NonRefArgumentToRefParameter,
                                     new object[] { i + 1, typeof(PSReference).FullName, "[ref]" });
                        }

                        var temp = Expression.Variable(parameterType.GetElementType());
                        temps.Add(temp);
                        var psRefValue = Expression.Property(args[i].Expression.Cast(typeof(PSReference)), CachedReflectionInfo.PSReference_Value);
                        initTemps.Add(Expression.Assign(temp, psRefValue.Convert(temp.Type)));
                        copyOutTemps.Add(Expression.Assign(psRefValue, temp.Cast(typeof(object))));
                        argExprs[i] = temp;
                    }
                    else
                    {
                        argExprs[i] = args[i].CastOrConvertMethodArgument(
                            parameterType,

Review comment (suggestion):
Please reword the comment.
It seems your comment in the PR description is more clear about behavior with `object`
> When it comes to the compiled assembly the ParameterInfo.DefaultValue for an argument with only [Optional] is [System.Reflection.Missing](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.missing?view=net-8.0) but this value cannot be passed as an argument unless the type is object because it cannot be casted to the argument type. Instead using null or the default value for that type should be used.

Code after:
                    {
                        var arg = args[i].CastOrConvertMethodArgument(
                            parameterType,
                            paramName,
                            mi.Name,
                            allowCastingToByRefLikeType: false,
                            temps,
                            initTemps);
                        argExprs[i] = arg;
                    }
                }
                else if (i >= args.Length)
                {
                    Diagnostics.Assert(parameters[i].IsOptional,
                        "if there are too few arguments, FindBestMethod should only succeed if parameters are optional");
                    var argValue = parameters[i].DefaultValue;
                    if (argValue == null)
                    {
                        argExprs[i] = Expression.Default(parameterType);
                    }
                    else if (!parameters[i].HasDefaultValue && parameterType != typeof(object) && argValue == Type.Missing)
                    {
                        // If the method contains just [Optional] without a default value set then we cannot use
                        // Type.Missing as a placeholder. Instead we use the default value for that type. Only
                        // exception to this rule is when the parameter type is object.
                        argExprs[i] = Expression.Default(parameterType);
                    }
                    else
                    {
                        // We don't specify the parameter type in the constant expression. Normally the default
                        // argument's type should match the parameter type, but sometimes it won't, e.g. with COM,
                        // the default can be System.Reflection.Missing.Value and this value is handled specially.
                        argExprs[i] = Expression.Constant(argValue);
                    }
                }
                else
                {
                    if (parameterType.IsByRef)
                    {
                        if (args[i].Value is not PSReference)
                        {
                            return Compiler.CreateThrow(typeof(object), typeof(MethodException),
                                     new[] { typeof(string), typeof(Exception), typeof(string), typeof(object[]) },
                                     "NonRefArgumentToRefParameterMsg", null, ExtendedTypeSystem.NonRefArgumentToRefParameter,
                                     new object[] { i + 1, typeof(PSReference).FullName, "[ref]" });
                        }

                        var temp = Expression.Variable(parameterType.GetElementType());
                        temps.Add(temp);
                        var psRefValue = Expression.Property(args[i].Expression.Cast(typeof(PSReference)), CachedReflectionInfo.PSReference_Value);
                        initTemps.Add(Expression.Assign(temp, psRefValue.Convert(temp.Type)));