Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update simple-lambda-parameters-with-modifiers.md #8910

Merged
merged 3 commits into from
Jan 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions proposals/simple-lambda-parameters-with-modifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,66 @@ The following change is required to [anonymous function conversions](https://git
> If F has an explicitly **or implicitly typed parameter list**, each parameter in D has the same type and
> modifiers as the corresponding parameter in F ignoring params modifiers and default values.

### Notes/Clarifications

`scoped` and `params` are allowed as explicit modifiers in a lambda without an explicit type present. Semantics
remain the same for both. Specifically, neither is part of the determination made
[in](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#12192-anonymous-function-signatures):

> If an anonymous function has an explicit_anonymous_function_signature, then the set of compatible delegate
> types and expression tree types is restricted to those that have the same parameter types and modifiers in
> the same order.

The only modifiers that restrict compatible delegate types are `ref`, `out`, `in` and `ref readonly`.
For example, in an explicitly typed lambda, the following is currently ambiguous:

```c#
delegate void D<T>(scoped T t) where T : allows ref struct;
delegate void E<T>(T t) where T : allows ref struct;

class C
{
void M<T>() where T : allows ref struct
{
// error CS0121: The call is ambiguous between the following methods or properties: 'C.M1<T>(D<T>)' and 'C.M1<T>(E<T>)'
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved
// despite the presence of the `scoped` keyword.
M1<T>((scoped T t) => { });
}

void M1<T>(D<T> d) where T : allows ref struct
{
}

void M1<T>(E<T> d) where T : allows ref struct
{
}
}
```

This remains the case when using implicitly typed lambdas:

```c#
delegate void D<T>(scoped T t) where T : allows ref struct;
delegate void E<T>(T t) where T : allows ref struct;

class C
{
void M<T>() where T : allows ref struct
{
// This will remain ambiguous. 'scoped' will not be used to restrict the set of delegates.
M1<T>((scoped t) => { });
}

void M1<T>(D<T> d) where T : allows ref struct
{
}

void M1<T>(E<T> d) where T : allows ref struct
{
}
}
```

### Open Questions

1. Should `scoped` *always* be a modifier in a lambda in C# 14? This matters for a case like:
Expand Down