Support optional and named arguments in Expression trees

Note

This article is a feature specification. The specification serves as the design document for the feature. It includes proposed specification changes, along with information needed during the design and development of the feature. These articles are published until the proposed spec changes are finalized and incorporated in the current ECMA specification.

There may be some discrepancies between the feature specification and the completed implementation. Those differences are captured in the pertinent language design meeting (LDM) notes.

You can learn more about the process for adopting feature speclets into the C# language standard in the article on the specifications.

Champion issue: https://github.com/dotnet/csharplang/issues/9246

Summary

Support optional and named arguments in method calls in Expression trees

Motivation

Errors are reported for calls in Expression trees when the call is missing an argument for an optional parameter, or when arguments are named.

This results in unnecessary code and differences for expressions within Expression trees. And lack of support for optional arguments can lead to breaking changes when a new overload with an optional parameter is applicable at an existing call site.

The compiler restrictions should be removed if not needed.

For example, compiling the following with the .NET 10 preview SDK results in errors currently.

namespace System
{
    public static class MemoryExtensions
    {
        public static bool Contains<T>(this ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer = null);
    }
}

Expression<Func<int?[], int, bool>> e;
        
e = (a, i) => a.Contains(i); // error CS0854: expression tree may not contain a call that uses optional arguments
e = (a, i) => a.Contains(i, comparer: null); // error CS0853: expression tree may not contain a named argument specification

Detailed design

Remove the error reporting for these cases in Expression trees, and allow the existing method call rewriting to handle optional and named arguments.

Drawbacks

Alternatives

Unresolved questions

It's unclear why the restrictions were added originally. An initial investigation hasn't revealed an issue supporting these cases.

Design meetings

Based on a suggestion from @roji to support optional parameters.