meetings/2021/LDM-2021-07-12.md
https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md#c-next
We spent the first half of today going through the remaining features that are currently being worked on by the compiler team and prioritizing them for what is going to make C# 10, and what will need to be pushed out to early preview for C# 11. Of the things still under C# Next, the current statuses are:
CallerArgumentExpression and InterpolatedStringHandlerArgument in C# 10. However, it is unlikely to be prioritized enough for C# 10.When we initially shipped top-level statements in C# 9, we made the decision that the type and method that the statements generated should be unspeakable. Our reasoning here was that the only reason the type or method would be needed would be for reflection to obtain the assembly, and users could use another type in the assembly for this. However, as work continues on the lighter ASP.NET feather templates, we are encountering scenarios where there actually aren't any other types in the user's assembly, which makes obtaining the assembly for unit testing very complex. To address this, we considered a mechanism to make the type and method speakable by user code. We have a few main axes of choice for a proposal, several of which are tied together:
First, we looked at the breaking change. We believe we would name the type Program and the method Main, following long C# template tradition, so our real question is "who is going
to create a program that is using top-level statements and has a type named Program?". We believe this to be a sufficiently small number of users that we are ok with the breaking
change. At the same time, we also looked at whether we should only generate the type when the user's language version is set to the appropriate version, meaning that C# 9 would still
generate an unspeakable name. After some consideration, we don't think that it's worth it to have separate generation strategies, as it will complicate the code for very little chance
of breaking. It does mean that there is the potential for someone to upgrade the compiler and not the language version and observe a breaking change from a different assembly, but we're
ok with this.
Next, we looked at the various levels of speakability. Only allowing the type to speakable by external assemblies is the minimal change to make, but it feels oddly inconsistent. Similar reactions were had for the method name: while we don't have a specific scenario currently for the method naming being speakable, we feel it would simplify the mental model for either everything to be speakable, or nothing to be speakable. We've always had the view that top-level statements are simply a sugar over a Main method in some type, and now we solidify that view by adjusting the sugar to this:
using System;
Console.WriteLine(GetInt());
static int GetInt() => 1;
desugars into:
using System;
partial class Program
{
public static void Main()
{
Console.WriteLine(GetInt());
static int GetInt() => 1;
}
}
By only specifying partial class, the type defaults to internal visibility, and we allow any other partial parts to be explicit about the visibility of the type and change it
however they choose. We will also change the signature of main based on the content, as we already do today with args and await.
We will adopt the above desugaring for top-level statements. This will introduce a break for any programs that have a non-partial Program type in the global namespace, or have a
partial Program type in the global namespace that is either not a class or defines a method named Main if that program is using top-level statements.