# C# Language Design Meeting for April 27th, 2026

## Agenda

- [Relaxed partial ordering](#relaxed-partial-ordering)
- [Labeled break and continue](#labeled-break-and-continue)
- [Null-conditional await](#null-conditional-await)
- [Chained relational comparisons](#chained-relational-comparisons)
- [Compound assignment in initializers](#compound-assignment-in-initializers)
- [Prioritization](#prioritization)

## Quote(s) of the Day

- "`ref partial struct` means the ref struct can only have fields of partial types, right?"
- "If you want bang for the buck we can always bring back `param!!`"

## Discussion

We examined a number of previously approved smaller features for which implementation PRs now exist, made some design adjustments, and ranked the features in terms of priority of adoption.

### Relaxed partial ordering

Champion issue: https://github.com/dotnet/csharplang/issues/9804  
Spec: https://github.com/dotnet/csharplang/blob/0b5d92e54c4bd74dfdfe85ac0f11363a4cc57af4/proposals/relaxed-partial-ref-ordering.md

For historical context, when partial types were first introduced in C# 2, there were concerns about contextual keywords, so the language mandated that `partial` must come immediately before `class`, `struct`, or `interface`. Since then, the language has added many contextual keywords such as `file`, `required`, and others, and the compiler has become sophisticated enough to parse them in any order without difficulty.

This feature is one of the simplest to implement. It allows the `partial` modifier to appear in the modifier list at any position, just like other modifiers. The implementation is trivial because the compiler already handles similar flexibility for other modifiers.

The proposal relaxes both `ref` and partial ordering. However, `ref readonly` and `readonly ref` mean different things in member signatures and could have distinct meanings on type declarations in the future. If we allow free reordering of `ref` and `readonly`, it could limit future language options. The team agreed that `ref` ordering requires more careful consideration. We proceed only with relaxed `partial` ordering for now.

#### Conclusion

Relax the ordering of the `partial` modifier so it can appear anywhere in the modifier list on type declarations. Not approved at this time: relaxing the `ref` modifier ordering on type declarations.

### Labeled break and continue

Champion issue: https://github.com/dotnet/csharplang/issues/9875  
Spec: https://github.com/dotnet/csharplang/blob/0b5d92e54c4bd74dfdfe85ac0f11363a4cc57af4/proposals/labeled-break-continue.md

This feature allows labels to be attached to loops and switch statements (which was already valid syntax but had no semantic meaning), and allows `break` and `continue` statements to reference those labels. If a label is placed on a loop or switch, then `break` and `continue` can target that labeled construct.

Implementation-wise, this is very inexpensive. Many modern languages support this feature, and it feels like a natural fit for C#. 

#### Conclusion

Approved as is.

### Null-conditional await

Champion issue: https://github.com/dotnet/csharplang/issues/8631  
Spec: https://github.com/dotnet/csharplang/blob/0b5d92e54c4bd74dfdfe85ac0f11363a4cc57af4/proposals/null-conditional-await.md

The motivation for this feature comes from common patterns where nullable async operations are encountered. When you have an expression like `GetX()?.DoSomethingAsync()`, the whole expression can return null. Today, the only way to handle this is to assign to a local, check if it's not null, and then await it separately. With `await?` syntax, you can write `await? GetX()?.DoSomethingAsync()` directly.

The feature almost entirely falls out of the existing specifications for `await` and the null-conditional `?.` operator; they compose cleanly and naturally. The compiler implementation is also very clean, and the feature works well with both traditional state machine emit and the new .NET async emit introduced in recent runtime versions.

This addresses a real pain point in nullable code. In a language that embraces null-awareness, patterns like this are common, and currently the workarounds are cumbersome and annoying. As the language continues to lean into nullable semantics, patterns like the null-conditional operator should extend naturally to async contexts.

#### Conclusion

Approved as is.

### Chained relational comparisons

Champion issue: https://github.com/dotnet/csharplang/issues/8861  
Spec: https://github.com/dotnet/csharplang/blob/0b5d92e54c4bd74dfdfe85ac0f11363a4cc57af4/proposals/chained-relational-comparison.md

This feature allows chaining relational operators, so instead of writing `a < b && b < c && c < d`, you can write `a < b < c < d`. The semantics are that each middle operand (like `b` and `c`) is evaluated exactly once, operations are evaluated left to right, and the overall expression short-circuits - if any comparison is false, subsequent comparisons are not evaluated.

This feature is particularly useful for mathematical and range checking code. The somewhat verbose workaround of combining comparisons with `&&` has been a minor pain point for people doing mathematical work in C#. While the team has lived a long time with traditional semantics and many languages do not support this, it is a common feature in more mathematical languages like Python. The feature feels elegant and natural.

Some team members noted this is not without dragons. There will be interesting interactions with generics and parsing (especially around `<`), and the implementation will be more involved than some of the simpler features. 

The feature also works well with new generic math operators.

#### Conclusion

Approved as is.

### Compound assignment in initializers

Champion issue: https://github.com/dotnet/csharplang/issues/9896  
Spec: https://github.com/dotnet/csharplang/blob/0b5d92e54c4bd74dfdfe85ac0f11363a4cc57af4/proposals/compound-assignment-in-initializer-and-with.md

The most compelling use case for this feature is events in declarative UI frameworks. Currently, event subscriptions cannot be performed in object initializers using `+=`, which forces developers to exit the declarative initializer syntax and write imperative code afterward. With this feature, you can write `new Button { OnClick += this.ClickHandler }` directly in the initializer.

However, the feature is designed to be general - it's not just for events but for any compound assignment operator. Just like regular assignments in object initializers, compound assignments translate into the normal statements you would write if doing it manually. All the same rules apply regarding property and field access, init accessors and dynamic dispatch.

The feature would be particularly impactful for functional declarative UI code. Today, when building deeply nested UI structures, you have to pull complex expressions apart into separate variables just to attach event handlers or other compound assignments, which breaks the flow of reading what the UI structure looks like. This is a source of real friction in UI development.

The proposal allows multiple compound assignments to the same member, as well as a regular assignment, which much come first if present.

During discussion we felt that a nested `P = { ... }` is special, and should not be allowed to coexist with compount assignments to the same member.

In addition, we felt that a `required` member in an object initializer must still be initialized with regular `=` assignment, which can then be followed by compound assignments. 

#### Conclusion

Approved with these changes:

1. Nested initializers cannot coexist with compound assignments to the same member, and
2. Required members must be initialized with a regular assignment.

### Prioritization

All of these features are simple and useful, and there was no strong agreement on which were more important. However, we were able to land on this ranking based on perceived impact and implementation cost:

1. Compound assignment in initializers
2. Labeled break/continue
3. Null-conditional `await`
4. Chained relational comparisons
5. Relaxed partial ordering
