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

Should the console project template use top-level statements #27420

Open
Tracked by #64487
tdykstra opened this issue Dec 6, 2021 · 837 comments
Open
Tracked by #64487

Should the console project template use top-level statements #27420

tdykstra opened this issue Dec 6, 2021 · 837 comments
Labels
discussion Indicates issues that are being discussed Pri3

Comments

@tdykstra
Copy link
Contributor

tdykstra commented Dec 6, 2021

For .NET 6, the console project template was changed to use top-level statements. The code that is created in Program.cs is:

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

In earlier versions of .NET and .NET Core, the code that is created in Program.cs is:

using System;
using System.Collections.Generic;
using System.Linq;

namespace MyApp // Note: actual namespace depends on the project name.
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

Discussion about whether this was a good change began in #26313 but there was some confusion about what exactly the various up or down votes applied to. This issue provides comments to vote on that clearly describe the options.

@PRMerger4 PRMerger4 added the Pri3 label Dec 6, 2021
@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label Dec 6, 2021
@tdykstra
Copy link
Contributor Author

tdykstra commented Dec 6, 2021

Up-vote this comment if you support the use of top-level statements in project templates.

@tdykstra
Copy link
Contributor Author

tdykstra commented Dec 6, 2021

Up-vote this comment if you prefer project templates to use the code created in previous .NET versions.

@tdykstra
Copy link
Contributor Author

tdykstra commented Dec 6, 2021

Up-vote this comment if you would like to be given a choice between top-level statements code and the code created in previous .NET versions.

@tdykstra tdykstra added discussion Indicates issues that are being discussed and removed ⌚ Not Triaged Not triaged Pri3 labels Dec 6, 2021
@PRMerger7 PRMerger7 added the Pri3 label Dec 6, 2021
@tdykstra tdykstra added Pri1 High priority, do before Pri2 and Pri3 and removed Pri3 labels Dec 6, 2021
@q00Dree
Copy link

q00Dree commented Dec 7, 2021

I'm sorry in advance, but what about ASP.NET Core templates like -webapi ?
I'd like to have choice between normal Startup.cs and Program.cs vs new Program.cs

@tdykstra
Copy link
Contributor Author

tdykstra commented Dec 7, 2021

what about ASP.NET Core templates like -webapi ? I'd like to have choice between normal Startup.cs and Program.cs vs new Program.cs

@Rick-Anderson do you want to create a discussion issue like this one in the ASP.NET Core repo?

@Rick-Anderson
Copy link
Contributor

I'm sorry in advance, but what about ASP.NET Core templates like -webapi ?
I'd like to have choice between normal Startup.cs and Program.cs vs new Program.cs

Use the ASP.NET Core 5 templates. Startup is fully supported.

@bravecobra
Copy link

Use the ASP.NET Core 5 templates. Startup is fully supported.

That is only temporary as those templates will be removed once .net core 5 is out of support. So, no, that is not a valid permanent solution to the problem.

@Rick-Anderson
Copy link
Contributor

The templates are not removed when .NET Core 5 goes out of support.

@DenisBabarykin
Copy link

The templates are not removed when .NET Core 5 goes out of support.

@Rick-Anderson can I create .NET Framework 4.5.1 template in VS 2022? Will I be able to create .NET Core 5 template in VS 2030? I don't think so. We want to make sure that the old-style explicit templates will be available in the future as well as the new one.

@Rick-Anderson
Copy link
Contributor

https://dotnet.microsoft.com/download/dotnet/1.1 is the .NET 1.1 SDK. Download that and you can create the ASP.NET Core 1.1 templates with VS 2022.

If you have complicated startup logic, you might want to keep using startup. But with complicated startup logic, the templates aren't much help.

@DenisBabarykin
Copy link

But with complicated startup logic, the templates aren't much help.

@Rick-Anderson If you think that you are right, then people will also support your opinion. Organize a vote and the question will be closed.

@luetm
Copy link

luetm commented Dec 8, 2021

In my opinion, the move to remove clutter is a very good one. I was also quite shocked when I first saw it, but when I teach coding to newcomers, it makes things so much easier. No more "just ignore all that stuff and focus on the things between the {}".

In general it's a very good direction follow, as long as there's no hidden functionality ("magic defaults"). With that I mean hidden behavior, for example implicit Console.Foo() statements that are executed if we use top-level statements, but aren't if we use the explicitly defined approach. If it's just things that get in the way, and add no value, remove it. What would be valuable would be a good way with tooling to 'escalate' to the cluttered view again if it's needed.

@symbiotic
Copy link

@tdykstra thanks for starting this issue

@bravecobra
Copy link

as long as there's no hidden functionality ("magic defaults")

But there is magic going on.
The signature of the program's entry-point method is deduced from your code. The only way to control it, is by changing your code (using await and return statements) since it's magically generated on-the-fly by the compiler.
The relevant magic can be found at https://github.com/dotnet/roslyn/blob/main/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSimpleProgramEntryPointSymbol.cs#L37

So, no, it doesn't get in the way and yes, it does add value. It makes the method signature explicit and it makes the syntax consistent with any other cs file. The idea of 'less is more' does not apply here, imho.
What used to be consistent by default, no longer is, by making namespace, class and method implicit. So, indeed, there are no more implicit Console.Foo() lines, which is a good thing, but now there is new implicit code/magic.

Keeping cs file syntax consistent over all files and learning the concept of classes and namespaces (which they would have to learn anyway at some point) seems an easier thing to understand for newcomers than compilers generating those classes and namespaces on-the-fly. I can see their questions like "Why is the syntax of Program.cs different from all the other files?" Answer: because the compiler can do magic.

In short, I think that syntax consistency wins easily over lines of code.

@died
Copy link

died commented Dec 9, 2021

BTW, can we have a MVC version Identity ?
After ASP.NET Core 2.1 Identity only provider as Razor pages and it was hard to customize, unless .NET team only doing "Hello World" level project, or only provide Razor version Identity was not smart move, like this "top-level statements" issue.

And .NET team only close issue to close our voice like #24181

@DefinitelyADev
Copy link

BTW, can we have a MVC version Identity ? After ASP.NET Core 2.1 Identity only provider as Razor pages and it was hard to customize, unless .NET team only doing "Hello World" level project, or only provide Razor version Identity was not smart move, like this "top-level statements" issue.

And .NET team only close issue to close our voice like #24181

Since that happened I/we tend to just do it manualy. Eg. create our own views and models and add the service injections. I/We also have abstracted the (User/Role/etc)-Manager using our own interfaces and implementations. So we just add my/our own library in my/our projects.

@ahwm
Copy link

ahwm commented Dec 9, 2021

No more "just ignore all that stuff and focus on the things between the {}".

IMHO if this is the style of teaching then the teaching needs to be fixed. Namespaces and class declarations aren't to be ignored but understood. Coding classes should start of with conceptual lessons (such as "what are classes?") before ever writing code. Especially with a language like C# where everything is object oriented. Without that foundation the differences between Console.Write() and objA.Write() would be confusing ("Why doesn't Console require new?").

For new students it might be sufficient to explain that it's a class declaration and that they would be explored more fully later. The new templates just abstract everything away to background magic and, as others have mentioned, make it even more confusing to understand why Program.cs behaves differently.

Also see this comment #26313 (comment) for good examples.

@ghost
Copy link

ghost commented Dec 10, 2021

This is too much abstraction away from the core. What if I wanted to use the async version? I have to create a .net 5 project and alter it. This is going a bit too far.

@svick
Copy link
Contributor

svick commented Dec 10, 2021

@dgxhubbard
Copy link

Bring old template back to net 6!

@AlexMcCown
Copy link

I see zero sense in abstracting main this heavily, please change it back and please don't let whoever made this decision make others.

The only possible use I can find for this is quick testing but that's what vscode is for.

@kaeaddaar
Copy link

First point: It is awesome being able to just write code and figure out how to program something new with an experience like this. Especially for simple demo apps, I'm loving it.

Second point: abstracting details away is a pain once you start to break out of the bubble and it begins to hide the clues to how you broke something in your program, or why things aren't behaving as expected. I find this type of thing horrible when I'm learning something new.

Final point: The experience that I feel is right would be able to be able to see the implied code, especially when debugging. If the code implied by or created by the compiler was shown when debugging then things would at least be clear. It's just a thought, but would source generators accomplish the same thing, and add clarity?

@Joebeazelman
Copy link

Joebeazelman commented Oct 26, 2022

Top-level statements offer no productivity gains, nor does it simplify the development process. In fact, it does the opposite. Removing all the ceremonial code leaves the experienced developer with an unsettling feeling of not knowing what's happening under the hood. This inevitably turns into another unnecessary and productivity-killing diversion into figuring it all out. Where are namespaces declared? How does it handle conflicting namespace, etc?

What do developers gain from this additional headache? Nothing. It's rare to write the ceremonial Program.cs, since most developers start from a project template. Even if it's written from scratch, it's not much code to type. Hiding it doesn't make the .NET platform any more approachable to new developers. It only obscures important details they should understand for any successful .NET development.

This horrible feature shows that Microsoft is way out of tune with the developer community. It harks back to when Microsoft CAPITALIZED MENU ITEMS ON VISUAL STUDIO'S MENUBAR because they thought it looked cool. It took a developer revolt before Microsoft retreated from the ill-advised UI change.

@yngndrw
Copy link

yngndrw commented Nov 8, 2022

When will this bug be fixed?

@ibetin
Copy link

ibetin commented Nov 17, 2022

Why? You saved 3 or 4 lines? What call stack should I expect for this code? What will actually run?

Please make this optional and off by default, make it opt-in

@mrickman-med
Copy link

One of the biggest fails in Microsoft history and just wasted 15 minutes of my life trying to figure out wth was wrong with my IDE.

@ccarlo88
Copy link

ccarlo88 commented Nov 18, 2022

One of the biggest fails in Microsoft history and just wasted 15 minutes of my life trying to figure out wth was wrong with my IDE.

Agreed and I would put this as the second biggest mistake as the first place goes to Xamarin/MAUI.
More interesting is that "normally" companies recognize mistakes and go back but nowadays some insist on them.

@mwwhited
Copy link

More interestingly is that "normally" companies recognize mistakes and go back but nowadays some insists on them.

I'd list no longer caring about backwards compatibility and expecting the "community" to clean up their obvious gaps.

@TanvirArjel
Copy link

@davidfowl @DamianEdwards Could you please read the comments and feedback here and take the necessary steps?

We are super frustrated with the way dotNET teams are handling the community feedback here. Almost everybody is irritated about the following things:

  1. Default top-level statement
  2. implicit using (this is the ugliest among all)
  3. mandatory NRT

@milanjaros
Copy link

My dear brothers in code,
you know that silence implies consent. Please consider that the reason why there are only thousands of disagreeing voices could mean that the rest of the developers are just fine with the change, and they don't feel the need to go and affect the solution.
You can opt out with dotnet new console --use-program-main.

@EvaldasPovilaitis
Copy link

My dear brothers in code, you know that silence implies consent. Please consider that the reason why there are only thousands of disagreeing voices could mean that the rest of the developers are just fine with the change, and they don't feel the need to go and affect the solution. You can opt out with dotnet new console --use-program-main.

@milanjaros, how do you define rest of the developers? Rest of the developers that use .NET 6/7? Or rest of the developers of .NET overall who might not even be aware of the changes being discussed and disliked or simply because they use other versions of .NET and simply do not feel pain at the moment. Or people might not be aware of this GitHub and do not where to let they voice to be heard.

For your statement that silence means consent this issue and people who voted here are factual contradictions. Also, if you look at the other voted issues, you'll see they do not have that many votes as this one. So, hypothetically speaking it's more likely that the opposite to your statement is true :)

@mwwhited
Copy link

Based on development periods for many dev shops there are places that started using .Net Core 3.1 (or are even still on 4.8) that don't even know this is an issue. Just wait until Jan 1 when 3.1 is deprecated. The difficult upgrade path and poor backwards compatibility of some things like EF and Jobs will really get start lighting some fires. As will the WTFs following "File New Project".

@huancz
Copy link

huancz commented Nov 22, 2022

@TanvirArjel This bug is about default top level statements. There's a lot of hate around that, argued in many posts here (justified as far as I'm concerned. Plague in all kinds of apps, not just console ones. Any kind of app worth writing has use for proper Program.cs (and Startup.cs)).

Implicit using - this has yet to bite me in any way. If there is problem with it, it deserves it's own bug where those use cases can be explored. I can't think of any, my position is "indifferent".

NRT - I think this is one the best thing that happened to c# since lambdas. Unlike TLS, it does add something valuable. Worth the pain to have to change one line in newly created .csproj if you know you are not prepared to deal with it. If you are new to c#, you are better off learning in NRT-enabled environment. Again - if there is an issue, it needs much deeper discussion than unclear oneliner here.

If you are trying to raise awareness at least link something showing those issues. I think your "almost everybody" group will be rather small if you try to push unrelated issues through it. Don't count me in, I'm here just to watch if they do something with TLS.

@EvaldasPovilaitis
Copy link

EvaldasPovilaitis commented Nov 22, 2022

@TanvirArjel This bug is about default top level statements. There's a lot of hate around that, argued in many posts here (justified as far as I'm concerned. Plague in all kinds of apps, not just console ones. Any kind of app worth writing has use for proper Program.cs (and Startup.cs)).

Implicit using - this has yet to bite me in any way. If there is problem with it, it deserves it's own bug where those use cases can be explored. I can't think of any, my position is "indifferent".

NRT - I think this is one the best thing that happened to c# since lambdas. Unlike TLS, it does add something valuable. Worth the pain to have to change one line in newly created .csproj if you know you are not prepared to deal with it. If you are new to c#, you are better off learning in NRT-enabled environment. Again - if there is an issue, it needs much deeper discussion than unclear oneliner here.

If you are trying to raise awareness at least link something showing those issues. I think your "almost everybody" group will be rather small if you try to push unrelated issues through it. Don't count me in, I'm here just to watch if they do something with TLS.

@huancz, l if you read all the comments you'll know it's not just about TLS and @TanvirArjel is right. TLS and Implicit Usings obfuscate essential code necessary to understand the program. Also, NRT is something you would benefit in a more complicated application, so having it enabled by default does not make much sense. Reference types are nullable and should be treated that way by default and all the help from compiler to change your coding habits should be optional and off by default. Especially when you are learning to code. Forcing compiler to forget by using ! is so stupid and irritating for example (https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/generate-consume-asynchronous-stream)

image

This is exactly what you would normally call a code smell. Thanks god they have abandoned the idea to validate if parameter is null by using !!

People click like for: Up-vote this comment if you prefer project templates to use the code created in previous .NET versions.

@ccarlo88
Copy link

@EvaldasPovilaitis oh my god, I didn't even notice this outrageous exclamation point. You are right, nullable is nullable and that's it.
Nadella should be replaced ASAP and a new CEO should come in before more damage is done.

@milanjaros
Copy link

milanjaros commented Nov 27, 2022

@EvaldasPovilaitis, yes, it isn't easy to measure. That's the reason I wrote: "it could mean". I wanted to point out that the 1210 number is caused by "a lot of hate around that" (@huancz) when you see something different than you expect when you run dotnet new console. The issue is one year old, and I would hope that the most significant part of developers creates one new console app at least once a year - this is to explain the statement "silence means consent". If there were that much hate and irritation, I would expect the number to be one order higher.

if you look at the other voted issues, you'll see they do not have as many votes as this one.

Agree. This is a valid point, and it did not come to my mind initially when I saw the number.

it's more likely that the opposite to your statement is true

Is it? I don't know. I don't have data.


@TanvirArjel, I've heard a lot of positive feedback about "implicit usings", NRT (I agree with @huancz) and default top-level statements. I also prefer it this way. Tom Dykstra asked for feedback, so "if you prefer project templates to use the code created in the previous .NET versions", please use dotnet new console --use-program-main to opt-in.


@EvaldasPovilaitis, do you create a simplistic (single purpose) application more often with dotnet new console or rather a "more complicated application"? Wouldn't you instead use a custom template (with more enhancements) for these complicated ones? Bear in mind you still can opt in.

TLS and Implicit Usings obfuscate essential code necessary to understand the program.

There will always be some level of "obfuscation". For example, the Main() method runs automagically when an application is started. A compiler generates the boilerplate for you, and you can just return int or use await - I find it brilliant.
The most important arguments are explained in the docs:

Top-level statements let you write simple programs for small utilities such as Azure Functions and GitHub Actions. They also make it simpler for new C# programmers to get started learning and writing code.

You can always disable NRT with directives (I would do that for such examples, as you posted) or per project (see nullable contexts). Please note that Tony Hoare apologized for inventing the null reference. He said

I call it my billion-dollar mistake.

@EvaldasPovilaitis
Copy link

@milanjaros, please read the comments on this issue and you will find answers. What you're asking has been discussed over and over again with CyrusNajmabadi. Unless you are here to replace him, and it all starts all over again? :)

I believe none of whom voted finds this "dotnet new console --use-program-main" acceptable but more or less an insult after how much time we spent here to bring back what was totally fine. People are arguing that there is no added value but opposite with TLS, NRT, and implicit usings in the templates. MS obsession to make C# more approachable will make another monster as C++ with n implementation of string just here with horrendous syntax used by newbies and no one else, or where the pro's/experienced users don't get the new syntax which also does not add value.

People who voted finds TLS, NRT, Implicit usings downgrade of the language or at least as something shouldn't be enabled by default. Implicit Usings goes straight against single responsibility/separation of concerns principles. When I create a new console app in VS to test something I don't want to keep turning Implicit usings, NRT off. Why? The same with TLM if I want to onboard I could simply create a new console app click Ctrl+A; Delete and start typing. But the opposite does not work as I'm forced to retype the whole namespace, class, and method.

So, after much reading, listening to MS, talking with colleagues and likeminded people here the conclusion is still one "This does not make sense".

@TanvirArjel
Copy link

@milanjaros Look at it! What people think about your opinions:

image

@TanvirArjel
Copy link

TanvirArjel commented Nov 27, 2022

@milanjaros

@TanvirArjel, I've heard a lot of positive feedback about "implicit usings", NRT (I agree with @huancz) and default top-level statements. I also prefer it this way. Tom Dykstra asked for feedback, so "if you prefer project templates to use the code created in the previous .NET versions", please use dotnet new console --use-program-main to opt-in.****

That's fine! In previous .NET version templates, there were no NRT and implicit usings but dotnet new console --use-program-main has. Why are you not removing the NRT and implicit usings from dotnet new console --use-program-main.

Sorry to say that! You guys are not even true to your words!

If you remove NRT and implicit usings from dotnet new console --use-program-main we will be at least happy!

@Balkoth
Copy link

Balkoth commented Nov 28, 2022

Updated for .NET7: https://github.com/Balkoth/ClassicConsoleTemplate

@ccarlo88
Copy link

ccarlo88 commented Nov 28, 2022

@milanjaros Positive feedback from which group? The Python programmers who create 1 micro-microservice for each task? The group who likes the feature but in the end go back and do it in Python? The feedback you need to listen is from C# programmers, not Python programmers. If Python was good no one would use C#.

@derempoukas
Copy link

derempoukas commented Nov 28, 2022

Fake simplicity for the sake of looking busy.
This whole idea is the new Clippy
image

@milanjaros
Copy link

We can joke about it, and we can disagree about it, but that's all we can do against it.

@MrChenLearnSpace
Copy link

Do not support, gild the lily, quickly change back, it is recommended to add this setting in the options, for later generated projects can automatically close this function, thank you

@Joebeazelman

This comment was marked as off-topic.

@ccarlo88

This comment was marked as off-topic.

@derempoukasm

This comment was marked as off-topic.

@mwwhited

This comment was marked as off-topic.

@mwwhited

This comment was marked as off-topic.

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Dec 19, 2022

The topic is about project templates. Discussing things like hiring practices or the zune (which was in 2006) is just about as off topic as one could get on this subject. This also includes grievances on other unrelated technologies (like azure functions). If you have feedback on those tools and technologies, there are other suitable locations to bring that up.

Wrt other languages, I can say that that wasn't what we were thinking about when doing these features. As the main designer of one of them (file scoped namespaces), and a codesigner on many others, I can say that it goals were to bring the benefits we found with our REPL experience in c# interactive to the majority of programs.

Clearly the ideas are polarizing for some. So we've provided knobs and options to disable all the things that are not desired. If you're having issues with those, or want to bring up some case that hasn't been considered , please let use know what those cases are. However, please keep those new issues on topic and constructive. We're all devs here, and we can keep things grounded on the project templates. Thanks!

@dotnet dotnet locked as too heated and limited conversation to collaborators Dec 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
discussion Indicates issues that are being discussed Pri3
Projects
None yet
Development

No branches or pull requests