-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Proposal: Project level using statements #2044
Comments
This means that to understand the meaning of any C# file, you'd need to take a look at the project file, or even at every file in the project with the One specific problem I see with this, especially the For instance: // Extensions1.cs
namespace Extensions1
{
public static class Extensions1
{
public static void DoStuff( this int n, object o ) { /*...*/ }
}
}
// Extensions2.cs
namespace Extensions2
{
public static class Extensions2
{
public static void DoStuff( this int n, int n2 ) { /*...*/ }
}
}
// Program.cs
using Extensions1;
public class Program
{
public static void Main( string[] args )
{
123.DoStuff( 456 );
}
} Adding a global using for |
@yufeih, are you aware that you can declare using directives at the top of the compilation unit (usually a code file) and at the top of the namespace declaration body? What you are looking for already exists and it's called Visual Basic |
@SolalPirelli You already need the knowledge of assembly references in the project file to understand and resolve the type names, so this is probably not something new. The global using should be a fallback when the namespace is not found in the cs file. In your example, because |
@paulomorgado I think what I am trying to achieve is to reuse using statements across multiple code files, not multiple code blocks within a single file. For instance: // File1.cs
using System;
using System.Linq;
public class File1 { /* */ } // File2.cs
using System;
using System.Linq;
public class File2 { /* */ } I'd like to simply write: // File1.cs
public class File1 { /* Code that uses types under System and System.Linq */ } // File2.cs
public class File2 { /* Code that uses types under System and System.Linq */ } // project.json
{
"namespaces": [
"System",
"System.Linq"
]
} I am not a VB guy but in C# there is currently no way to do that. |
@yufeih, the differences between C# and VB exist because different people want different things. And it looks like you want to be a VB developer. I like to have my using directives on the file and only the ones that are needed. And I like to decide if I want the using directives inside or outside of the namespace declaration. |
@paulomorgado is correct that VB already has this. You will see the following in almost all .vbproj files: <ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup> These namespaces are included automatically for every file in the project. The question is: Why does VB have this and C# doesn't? The main reason is philosophical: VB and C# have different design philosophies. While not always true, C# likes to explicitly show the user what is happening (always showing which namespaces are being used at the top of the file) whereas VB is willing to hide things if it saves 90% of the users time or complexity (auto import common namespaces). We would need to add the Imports functionality from VBC to CSC and plump all the options through the compiler. If someone feels strongly about this and we can all come to consensus about wanting it to happen, this seems like a reasonable thing to submit a pulI request for. |
I'm going to add one more item to this proposal: project-level type aliases, with a similar syntax. This is something that many people have been asking for years. Something like this (borrowing the syntactic scope qualifier from attributes): assembly:using Pair = System.Tuple<System.Int32, System.Int32>; Alternative syntax: global::using Pair = System.Tuple<System.Int32, System.Int32>; Assuming that we have a C# syntax for it (as opposed to a metadata file, like in VB), both kinds of usings could go in a separate file (similar to how |
Exactly, @jmarolf. It's philosophical. Are we changing the philosophical? |
While you are at it, @apskim, why not proposing a project wide namespace for every type without the namespace declaration? |
I personally prefer the explicit approach currently taken in C#. Visual Studio's |
@paulomorgado if you want my opinion, probably not, but I don't speak for everyone. I would imagine that most C# developers feel it is simpler to have one source of truth for what namespaces are included in a file. I imagine most VB developers like not having to see boilerplate import statements at the top of their file. Lets have the discussion to see if this is a correct assumption. |
@jmarolf I think for philosophy, it is more about giving people choice and let them decide for their own. This is like the The comparison is probably not fair because a lot of C# developers (like me) are not aware of such thing in VB. If C# has the same concept from day 1, they might get used to it. |
@yufeih, |
I find this feature in VB very irritating. We used to have some utility classes we could include in some of our old vb projects that defined internal classes we didn't want to expose to users. At some point someone thought it was a good idea to switch to project level imports for an ever growing number of such imports. For a few months our builds broke here and there where someone moved an import to project level but didn't update every project that used the file. |
I'd rather see a feature by where a namespace automatically includes other namespaces. Not sure how it would semantically work, but something like:
In this way, any use of the namespace in another file would automatically include the namespace included files.
The suggestion by @apskim is also fairly good, though I'd like to add a twist to it:
|
We would not do this in C# because the name lookup rules would then depend on things outside the language (or, to put it another way, it would extend the language to the contents of other "files" and we don't want to add the format of those other files to the language specification). |
Problem
All C# code starts with a list of
using
statements. For a large project, it is not uncommon for each file to contain more than 20 lines of using statement at the top. When moving code around, a lot of time is wasted managing namespaces.IDE can help import and remove unused namespaces, but the problem itself does go away.
I propose to have a project level using statements, because files within a project are likely to share a set of common namespaces. With that, using statement inside the code file is used more for conflict resolution.
Design
There are couple of ways to do it and I personally prefer the first approach because it integrates well with the new project file format.
project.json
.project.json
is a separate thing from Roslyn, so for Roslyn, this means csc.exe taking extra parameters just like how references are specified.using global System.Collections.Generic
inside a cs file, just like how global attributes are specified.The text was updated successfully, but these errors were encountered: