This question already has answers here:
Should 'using' directives be inside or outside the namespace in C#?
(13 answers)
Closed 9 years ago.
I was learning MVC WebAPI and I was following a tutorial and everything was going fine untill I saw the following:
namespace HelloWebAPI.Controllers
{
using System;
public class ProductsController : ApiController
{
}
}
What we usually do is that we add the resources\scope in the beginning like this:
using System;
namespace HelloWebAPI.Controllers
{
public class ProductsController : ApiController
{
}
}
I want to have a better understanding about it
Thanks.
There is a difference, small but there is.
It's all about the sequence of name resolution made by compiler.
The good answer on subject you can find here:
Should Usings be inside or outside the namespace
In practise in first case compiler, in case could not find a type information immediately,
would search among namespaces declared inside using. In second case, instead, would search first among the actual namespace and after only go to search inside declared outside.
You can define more than one namespace in a C# file.
Putting using statements inside of a namespace means they are only in use within that namespace for that file.
Putting them outside of the namespace means they apply for all namespaces within the file.
It's kind of how the scope of variable names applies only in the most inner braces that contains them and deeper.
The only difference is with scope of using statements. If you use using inside a namespace then these using statements will be included in all files which place under that namespace. And if you use using statements outside namespace then these using statements will be valid only for current file.
File 1:
namespace MyNamespace
{
using System;
using System.IO;
public MyClass
{
}
}
File 2:
namespace MyNamespace
{
public MyClassV2
{
}
}
In this example you don't need to add using in File 2 for MyClassV2 as MyNamespace already has these using statements. But for a different namespace you need to add using statements.
Related
I have been looking around for a while now to see how can I enforce my C# projects to have full namespace path.
For example actual if namespace for class X is Foo.Bar.Car.Dealer when doing Ctrl+. in visual studio it sometimes puts statement like using Car.Dealer; this specially becomes a problem with multiple projects solution. I have been looking around for StyleCop rule or something that might help me get this done.
Any help or ideas?
EDIT
The above statement holds true only if the using class falls under same namespace prefix. Here is complete code example:
File: X.cs
namespace Foo.Bar.Car.Dealer {
class X {}
}
File: UsingClass.cs
namespace Foo.Bar.Another.ClassPath {
using Car.Dealer;
class UsingClass {
private X _x;
}
}
The VS picked using Car.Dealer but I want to enforce using Foo.Bar.Car.Dealer
I do not know about versions prior to 2012, but from then on the icon that pops up for action upon coming across an unknown type offers both adding the namespace via using directive or to simply prefix the type being referenced by the full namespace.
If you do not want to add the namespace via using directive (which would look like using Foo.Bar.Car.Dealer;),
then in your example you simply need to reference your type X as Foo.Bar.Car.Dealer.X.
Example:
//assuming your X type is instantiable
Foo.Bar.Car.Dealer.X myX = new Foo.Bar.Car.Dealer.X();
I am working on a T4 template which produces partial classes based on existing partial classes.
Sometimes the generated code will reference types being used from the existing (non-generated) codebase.
The generated code must either fully qualify these types, or mimic the using statements it finds in the non-generated code.
Mimicking using statements seems better since it will support cases where the type is being referenced from a [Attribute(typeof(Something))], where EnvDTE only returns the string literal "typeof(Something)".
So: how do I find these using statements? I'm using tangible T4's AutomationHelper, but still can't seem to find a solution :(
You can get the using statements by looking at the FileCodeModel.CodeElements for the ProjectItem.
Each ProjectItem has a FileCodeModel property. The FileCodeModel.CodeElements will contain a CodeImport for each using statement. Note that the FileCodeModel.CodeElements will contain other things not just CodeImportss o you will need to check the type returned or filter the unwanted types.
An example is shown below. Here I am using the NuGet's Package Manager Console and PowerShell.
$p = Get-Project
$fileCodeModel = $p.ProjectItems.Item("Class1.cs").FileCodeModel
$fileCodeModel.CodeElements | % { $_.Namespace }
The code above assumes there is a Class1.cs file in the root of the project. For each using statement it will print the full namespace. Note that in the above code it is trying to print the Namespace for each CodeElement and some of the elements will not have this property so you will need to restrict this so it only looks at CodeImport types. The above will work for the following class file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClassLibrary1
{
public class Class1
{
}
}
If you have using statements between the namespace ClassLibrary1 and the public class Class1 part you will need to do more work and look at the CodeNamespace members since the CodeImports will not be available directly from the FileCodeModel.CodeElements, but hopefully the above code should point you in the right direction.
I am just looking at a project and I'm seeing something working which I didn't think should work.
If you look at the snippet below I'm in the namespace CustomFields.DateTimeField.Drivers, and the only other using statements in that file are other namespaces below CustomFields.DateTimeField.
But if you look on the public class DateTimeFieldDriver line it is using a type Fields.DateTimeField.
Looking at the definition of DateTimeField thats in the namespace CustomFields.DateTimeField.Fields but I have only set usings for its sister namespaces.
So the question is twofold - why does this work? is this considered a bad practice?
Snippet in question:
using System;
using JetBrains.Annotations;
using Orchard;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Localization;
using CustomFields.DateTimeField.Settings;
using CustomFields.DateTimeField.ViewModels;
namespace CustomFields.DateTimeField.Drivers {
[UsedImplicitly]
public class DateTimeFieldDriver : ContentFieldDriver<Fields.DateTimeField> {
public IOrchardServices Services { get; set; }
private const string TemplateName = "Fields/Custom.DateTime"; // EditorTemplates/Fields/Custom.DateTime.cshtml
public DateTimeFieldDriver(IOrchardServices services) {
Services = services;
T = NullLocalizer.Instance;
}
The project can be downloaded here if you want to investigate it (MVC2 project).
When you declare code to be inside a particular namespace, for example, CustomFields.DateTimeField.Drivers, you are implicitly importing all the "parent" namespaces as well.
In this case, you have an implied using for CustomFields and CustomFields.DateTimeField. This is why you do not have to specify an explicit using statement for types in CustomFields.DateTimeField and furthermore, for subnamespaces contained therein.
Thus Fields.DateTimeField is found by combining CustomFields.DateTimeField (the implied namespace) with Fields.DateTimeField (the explicit namespace) to resolve to CustomFields.DateTimeField.Fields.DateTimeField.
And no, as far as I know this is not considered bad practice.
In C#, when you're within a namespace, you have implicit using for each of the parent namespaces. For example in this file:
using System;
namespace Foo.Bar.Baz {
class Qux {
}
}
\EOF
Is the same as this file:
using System;
using Foo;
using Foo.Bar;
namespace Foo.Bar.Baz {
class Qux {
}
}
\EOF
If you have a namespace imported, then you don't need to specify the full namespace to access members of a sibling namespace tree provided it has the same prefix as an imported namespace:
using Foo;
using Foo.Bar;
namespace Foo.Bar.Baz {
class Qux {
}
}
namespace Foo.Bar.Norf {
class Guf : Bar.Baz.Qux { // namespace `Foo.` is implicitly assumed to prefix the namespace reference `Bar.Baz`
}
}
\EOF
You're experiencing these two effects combined: implicit namespace prefix usage to an implicitly imported namespace.
As for "bad practice" - experienced C# developers will be familiar with this nuance, but generally it isn't a problem unless you have ambiguous names.
As a tip, try to minimize the number of namespaces and their depths. For example, in your case I see you're storing DateTime-specific stuff in its own DateTimeField namespace. This has a bad "code smell" to me. I would just put everything in the CustomFields namespace, especially as you've given each typename the prefix DateTime anyway, so it's just double-typing.
FxCop will complain if you have fewer than 5 types in a namespace too, btw.
Update: I took a look at the C# specification ( http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf ), section 16, but I can't find any part of it which states that parent namespaces are implicitly imported, which is strange.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Should Usings be inside or outside the namespace
Are there any technical reasons for preferring this
namespace Foo
{
using System;
using System.IO;
instead of the default
using System;
using System.IO;
namespace Foo
{
Eric Lippert explains this.
In general, they're identical.
However, using statements in the namespace can see namespaces and aliases included outside the namespace.
Almost* the only difference between the two would be if you used more than one namespace in the same file (or if you used the same namespace more than once). I'm not sure why would you do that, bu you certainly can:
using System;
namespace FooNamespace
{
using System.IO;
class Foo
{
// you can use types from System and System.IO directly here
}
}
namespace BarNamespace
{
class Bar
{
// you can't use types from System.IO directly here
// but you can use types from System
}
}
* See SLaks' answer.
No technical reason, just a preference. of course the second chunk of code looks cleaner, though.
If I have a namespace like:
namespace MyApp.Providers
{
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
}
Does this mean that if I create other files and classes with the same namespace, the using statements are shared, and I don't need to include them again?
If yes, isn't this a bit of a management headache?
No, it's only good for the namespace section inside the file. Not for all files inside the namespace.
If you put the using statement outside the namespace, then it applies to the entire file regardless of namespace.
It will also search the Usings inside the namespace first, before going to the outer scope.
You need to specify the using directive for any classes that you want to reference without qualification in each file where you want to use them.
Reference:
The scope of a using directive is
limited to the file in which it
appears.
No, it doesn't, and so no, it isn't.
Consider the fact that outside the namespace declaration, you are in the global namespace. Do using statements in that region of the source file affect the global namespace in other source files?
No. You'll need to include the namespaces in every class except on partial classes.
One side note: you're doing a very good practice of putting the using statements inside the Namespace. That's very good syntax.
Keep up the good work.
The using statements are valid for the code file in which they appear, with a minor twist; if you put the using statements inside the namespace, they are limited to the scope of that namespace, but still only within the same code file.
Usings only apply to the current file. Whether they're inside or outside the namespace declaration makes only a small difference:
The lookup order for types is as follows:
start in the innermost namespace declaration
look in the current namespace
look in the usings of the current namespace
go up to the parent namespace declaration and repeat from step 2
As a result, this program will compile fine:
namespace MyProject.Main {
using System;
class Program {
public static void Main(string[] args) {
Console.WriteLine("Hello, World!");
}
}
}
// in another file:
namespace MyProject.Console {
class Test {}
}
But if you move the using System; to the top, then the compilation will fail (MyProject.Console.WriteLine doesn't exist).