Open bomzj opened 7 years ago
@ssg - but of course... :( Maybe it should be a lang version thing then... for forwardness compat and not back-compat
@ahmedilyasms That would still break existing code migrating to the new version, which I think is a dealbreaker. None of the new C# features cause something like that.
@ssg - we have had this before I guess where certain feature work based on the lang version. But even then so, why would it be a difference in the code gen? It wouldn't AFAIK. We would still support having namespaces in the file but if 1 was NOT supplied, then it should take the default one as defined in the assembly.cs. This thought or approach would cater for both pre and post this proposal :)
@ahmedilyasms Your feedback is noted. However, what you are asking for is decidedly out of scope for my proposal/championing.
Thanks!
@ahmedilyasms
we have had this before I guess where certain feature work based on the lang version
The lang version should light up new features, but not change the behavior of existing code. C# has never required a namespace in a source file, and that has never meant to implicitly put the code under some namespace declared elsewhere. That would be a breaking change and create a dialect in the language.
I moved from PHP and as beginner in C# namespace declaration was very ugly for me compared to another parts of language so that I welcome all simplifications which help me with well-arrange simpler code because it's a reason why I moved to C# :)
Another benefit of this proposal is that it is in line with top-level statements which were introduced recently.
This would also be closer to F#'s namespace syntax, and I think that could be a good thing.
I only partially understand the "root namespace" comments above, but I for one have never seen a C# source file without a namespace declaration. If there is a potential backwards-compatibility issue here, perhaps it could be evaluated against code that's currently in GitHub to see what percentage of "real-world" projects would have a problem?
This would be out of scope of this proposal, but I wonder if the day might come where the namespace declaration is entirely unnecessary since (in my experience) well-structured projects always follow the folder-per-child-namespace pattern. Maybe in .NET 7/C# 11 the compiler could infer the namespace from the project + file path? ๐
This would be out of scope of this proposal, but I wonder if the day might come where the namespace declaration is entirely unnecessary since (in my experience) well-structured projects always follow the folder-per-child-namespace pattern. Maybe in .NET 7/C# 11 the compiler could infer the namespace from the project + file path?
I don't think I'll ever support that, at least. Roslyn itself is an example where we have a folder structure that slightly differs from the namespace structure.
I don't think I'll ever support that, at least. Roslyn itself is an example where we have a folder structure that slightly differs from the namespace structure.
That's totally fair, but also I'm assuming you have explicit namespace declarations within all Roslyn source files. (Bad on me that I haven't checked that assumption, of course.) So if hypothetically such a feature were to be added, it wouldn't impact the existing Roslyn codebase at all. Anyways, just a thought. I really like the theme of this proposal, and my 2ยข is that any change that removes unnecessary curly braces is a welcome one. Of course, that's coming from someone who only gave up wrapping single-line if/else branches with curly braces 3 years ago. ๐ The point is that giving people a choice could be a good thing in that it opens up the language to different ways of viewing the world -- like LINQ did for functional programming -- and that could lead to a new consensus over time about better ways of doing things -- like immutable data & record types.
Can we even go further and make the namespace dependent on the <RootNamespace>
in .csproj
and the path of the .cs
file? It's very common to organize code files with their namespaces into folders, and very often mistakes happen there. This must be optional off course.
/Product.csproj
<RootNamespace>Company.Product</RootNamespace>
/Feature/Implementation.cs
// use namespace without providing the namespace, this doesn't break with existing code, as it was not allowed so far
//
// it would be nice if you wouldn't need it at all, but it would break with existing code.
namespace;
class Implementation
{
// this class is now Company.Product.Feature.Implementation
}
It could even go one step further, derive the class name from the file name. This is probably a bad idea, but some ideas for completeness:
/Services/CronService.cs
// pull namespace and class name from filename/path
namespace;
class;
public static void Run()
{
// this is now Company.Product.Services.CronService.Run()
}
Off course some other things need to work too
// modifiers
public sealed class;
// structs
struct;
// records
record (double X, double Y);
// derived types, generics, ...
class : IDisposable;
class<T> where T: IDisposable;
@andi0b this probably won't happen. AFAIK one of the main goals of C# is that the compilation should never depend on the physical location of the source files (not to mention locations outside the project folder). This is a huge benefit compared to e.g. TypeScript where I need to rewrite all usings (imports) when moving a file.
@bachratyg: I think you mix two things:
AFAIK one of the main goals of C# is that the compilation should never depend on the physical location of the source files (not to mention locations outside the project folder).
This is true. There are examples where file names or locations of source files already matter:
Test.csproj
will result into setting AssemblyName
to Test
CallerFilePathAttribute
: the compiler takes file names and add information from there into the codeThis a huge benefit compared to e.g. TypeScript where I need to rewrite all usings (imports) when moving a file.
If you want to move files around and keep the name space, you can still use an explicit namespace definition. Most of the time you don't want to keep files with the same namespace in separate folders.
@bachratyg: I think you mix two things:
- csproj file name.
Test.csproj
will result into settingAssemblyName
toTest
That is not a language feature. It's entirely done by msbuild/sdk tooling/Roslyn Workspaces and not by csc. The language has no clue (and rightly so) about the project file format or semantics.
CallerFilePathAttribute
: the compiler takes file names and add information from there into the code
This is the same category as source information in stack traces: use it for debugging/diagnostics not your core logic otherwise it's your funeral.
If you want to move files around and keep the name space, you can still use an explicit namespace definition. Most of the time you don't want to keep files with the same namespace in separate folders.
I for one frequently factor out files of a feature to subfolders when the folder gets too crowded thus the namespace is usually the prefix of the path. Lots of people in this very same topic also consider java's package equals path as detrimental, I guess they won't prefer it either. That makes the usefulness of your proposal uncertain vs the cost of drastically changing a high level language construct.
@andi0b That has been discussed extensively before, perhaps refer to the previous discussion first: https://github.com/dotnet/csharplang/discussions/2908
File scoped static classes would be great too like F# modules. This is a cqrs example
namespace Users
{
public static class Create
{
public class Command
{
....
}
public class Handler
{
....
}
}
}
With scoped static class
module Users.Create;
public class Command
{
....
}
public class Handler
{
....
}
For all my files that have a single namespace (which is all of them so far, personal and work, including every file I've ever edited or read in an open source project), nothing would make me happier than this:
using System; public class My.Namespace.ClassName { }
And I do mean nothing. :-)
This thread is huge so apologies if this was already brought up.
While I agree with you @jnm2 that this would be a lot cleaner/simpler, it removes the possibility of adding using namespaces inside the namespace, like this:
namespace My.Namespace
{
using System;
public class ClassName
{
}
}
If the syntax you are proposing was to be allowed, I'd also like to see this being possible:
public class My.Namespace.ClassName
{
using System;
public ClassName()
{
...
}
public string SomeProperty { get; set; }
}
}
(i.e. namespace references inside the class).
Another problem with what I wanted is that it's not clear how it could work with nested classes, a prime use case for me. I think this would be best as a shortcut for wrapping with partial class C
:
namespace A.B;
class C.D
{
As of now, file scoped Namespaces don't work with VS2019 (both preview and non-preview). Is that intended and FSN considered to be a VS2022-only feature? If so, why isn't it properly documented? (at least I couldn't find any information about it) If not, why isn't it compiling in 2019?
@CleanCodeX FileScopedNamespaces are part of C# 10. So you'll need to use a tool that supports that version of the language. All our IDE support went into the 17.0.x line (i.e. VS2022).
It seems, people (including me) are a bit confused by the fact that some features are a feature of .NET and some of the C# compiler. Thanks for pointing it out. Sadly I could not find any list of C# 10 compiler features (not just NET6). Is there any list available what the C# 10 compiler will support for the final release? All lists I found do not distinguish between C# 10 and .NET itself. The NET6/C#10 feature lists I found are often labeled just as "C# 10 features" or "NET6 features" but obviously that isn't technically true.
@CleanCodeX FileScopedNamespaces are part of C# 10. So you'll need to use a tool that supports that version of the language. All our IDE support went into the 17.0.x line (i.e. VS2022).
My confusion is based on that: A female program manager from Microsoft (don't remember her name) said in a Youtube Dotnet stream: "if you can use the 'global using' keyword combination, you're using c#10." But, global usings work in VS2019, so c#10 support seems to be there and therefore FSN should also work, at least that was what I thought.
There were some preview features of 10 that went into VS2019. But that's all.
Will FSN find their way into VS2019 as well?
Will FSN find their way into VS2019 as well?
No. VS2019 is effectively locked down now, with only highly critical fixes being made there (think "bad crashes affecting millions"). Shipping preview features in it will not happen.
"if you can use the 'global using' keyword combination, you're using c#10."
This is correct. 'global usings' are part of C# 10.
But, global usings work in VS2019,
VS2019 has 'preview' support for 'some' C# 10 features. But it doesn't have 'final' support for 'all' c# 10 features. 'preview' allows people to test things out and gives us a chance to make thigns available earlier to get feedback. But not all features will make it into preview in a particular VS release. It will depend on when in the schedule we implement the feature in preview and how that aligns with particular VS schedules.
so c#10 support seems to be there and therefore FSN should also work, at least that was what I thought.
This is not something we guarantee. As per above, not all features make it into a preview release for a particular VS build. global-usings made it into a preview build for VS2019, FSN made it into a preview build for VS2022.
Will FSN find their way into VS2019 as well?
No. VS2019 is effectively locked down now, with only highly critical fixes being made there (think "bad crashes affecting millions"). Shipping preview features in it will not happen.
Sorry, I meant will FSN find their way into VS2019 preview as well?
Sorry, I meant will FSN find their way into VS2019 preview as well?
No.
Shouldn't this issue be closed? It went live in the last release right?
The ecma spec has not been updated for this yet, so it is not finished @mungojam .
@mungojam FYI, that's what the "Implemented needs ECMA spec" label on this issue means, although of course that's easily missed if one doesn't know to look for it ๐
@mungojam FYI, that's what the "Implemented needs ECMA spec" label on this issue means, although of course that's easily missed if one doesn't know to look for it ๐
That makes sense. I actually came here because it was listed on the future roadmap of c# changes and showing as open. Should it be removed from there?
Spec: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/file-scoped-namespaces.md
How it looks now:
Why do we need to nest our class definition in namespace ? Why not to remove extra nesting ? Isn't that better ?
LDM history: