If I import a namespace like this:
using System;
Why can't I access subnamespace IO like this:
IO.FileInfo fi;
Insted I must write either a whole path:
System.IO.FileInfo fi;
Or import whole IO namespace and use class without namespace
using System.IO;
FileInfo fi;
Am I missing something here?
While it's often convenient to think in terms of "namespaces" and "sub-namespaces", in reality, there are only type names.
In this case, there is a single type: System.IO.FileInfo
The using directive allows the compiler to add System. to any type to see if it finds a matching type name. However, this won't find IO.FileInfo, as it will be looking for a IO type, containing a FileInfo nested type.
The way the language is designed may seem more cumbersome, but it eliminates the confusion of nested type names vs. namespace names, since it only looks for types within the namespaces defined in the using directives. This reduces the chance of type naming collisions.
C# does not really have the concept of subnamespaces. The periods in the namespace name are just there for logical organization purposes.
System and System.IO are two different namespaces as far as C# is concerned.
If you just need the FileInfo class you could do this:
using FileInfo = System.IO.FileInfo;
What you are trying to do only works if the context type is in the same namespace hierarchy, e.g.:
namespace System {
class MyClass {
IO.FileInfo fi;
}
}
You can also have relative imports, like this:
namespace System {
using IO;
}
Related
I have a directory tree as such:
+Enums
|+MyEnums.cs
+Src
+Model
+MyModel.cs
And I would like to use the namespace Enums that I declared in MyEnums.cs in the file MyModel.cs. But I cannot figure out how to do such, because when using the code
using Enums;
I constantly get the error/warning that
The type or namespace name 'Enums' could not be found (are you missing a using directive or an assembly reference?)
If I use it in the same folder I have no issue, but I would like to use it across a larger directory tree.
The directory structure of your project and the structure of the namespaces are technically two unrelated things; nevertheless it makes sense to have them organized in parallel, but still they are orthogonal concepts. You have to define a namespace by putting types into it as follows.
namespace Enums
{
// some definitions
}
namespace Enums.MyEnums
{
// some more definitions
}
After populating the namespace, you can import the namesepace with the using directive.
Adding a file to a directory like that typically gives you a namespace that is the same as the directory name, but that is not necessarily the case (such as when you move a file from one folder to another). The namespace is determined like this in the file. Check what the namespace is and change it to Enums if that's what you want it to be:
using System;
namespace Enums
{
enum Testing
{
Test1,
Test2
}
}
This question already has answers here:
Importing nested namespaces automatically in C#
(7 answers)
Closed 9 years ago.
in c# if I want to add other System namespaces why do I need to call each namespace?
For example
if I want to call the System.Text namespace I have to use:
using System;
using System.Text;
why cant I just use using System?
Why do I also have to call using System.Text?
Why cant I use all System namespaces by just using System?
Why we use System for all namespace ?and what the meanings of system ?
the System namespace refers only to the files directly found under System. It does not automatically include all System.* namespaces. This is intended, since these are specialized namespaces which aren't needed in every class. Not every project automatically needs the System.Web namespace, for example.
You actually just need
using System.Text;
if you only want to use the System.Text namespace.
Within the System namespace, there are various types, eg System.DateTime. System.Text is not in System though, it is a separate namespace.
The confusion is caused by there being types at each "level" of a namespace. This means eg System.DateTime and System.Text both appear to be in System, when in reality the former is a type in System and the latter is a completely different namespace.
Here's a visual example that may help you out a little.
Basically, you can't access the namespace .Text from namespace .System because the methods contained within the .Text namespace do not exist in the .System namespace.
namespace OuterNamespace
{
public class DoStuff
{
public DoStuff()
{
//This DoStuff is different...
}
}
namespace InnerNamespace
{
public class DoStuff
{
public DoStuff()
{
//than this DoStuff.
}
}
}
}
public class Test
{
public Test()
{
//This "DoStuff" class
OuterNamespace.DoStuff outerStuff = new OuterNamespace.DoStuff();
//Is different than this "DoStuff" class
OuterNamespace.InnerNamespace.DoStuff innerStuff = new OuterNamespace.InnerNamespace.DoStuff();
}
}
Because they're different namespaces.
This article explains how to use Namespaces. Especially the example regarding Fully Qualified Names might be interesting to you.
System and System.Text are two different namespaces and that's why you had to refer both.
The System namespace contains fundamental classes and base classes that define commonly-used value and reference data types, events and event handlers, interfaces, attributes, and processing exceptions
The System.Text namespaces contain types for character encoding and string manipulation. A child namespace enables you to process text using regular expressions.
Now if you are confused about naming style then I would stick to Microsoft naming convention since it clearly isolate relating types and easy to iterate. This make stepped type iteration than listing all CLR types within one System namespace.
More about namespaces
I am creating a little Math library for myself contained within a single project and am running into some issues with namespaces. I have the project MyMathLib and the top level namespace:
namespace MyMathLib
{ ... }
and in a separate file...
namespace MyMathLib.Addition
{ ... }
and...
namespace MyMathLib.Subtraction
{ ... }
In the MyMathLib.Subtraction namespace I have a method that needs to use a static method SomeClass.Work() defined in MyMathLib.Addition so I included using MyMathLib.Addition at the beginning of the Subtraction file. But when I try to use the method it would like me to first qualify it with Addition.SomeClass.Work() and I want to be able to just type SomeClass.Work(). What am I doing wrong?
Thanks!
EDIT
Thanks for the suggestions! In each file, I actually named the class after the namespace (i.e. in the namespace MyMathLib.Addition is a static class Addition and in MyMathLib.Subtraction there is a static class Subtraction). Apparently this is what caused the issue (looking back, I should have stated this instead of using SomeClass). If I change the namespace to MyMathLib.MyAddition while keeping the static class as Addition, the using MyMathLib.MyAddition works as I want; that is, I can now just type Addition.Work() in my static Subtraction class. I've seen classes named the same as it's containing namespace before, could someone maybe explain why this is causing an issue? Shouldn't the compiler be able to determine whether I want to use the namespace or the class from the context of the code?
I'm guessing that you either have two classes called SomeClass that are both in namespaces you reference, or you have a variable or property named SomeClass. Either of these situations would make it impossible for the compiler to know that you're trying to call the static MyMathLib.Addition.SomeClass.Work() method, but the specific solution the compiler is suggesting makes it seem more likely to be the former.
Update
Seeing your edit, that makes sense. If you were using these in a namespace outside of MyMathLib, then you would still be able to avoid this namespace conflict. However, because you are inside the MyMathLib.Subtraction namespace, the compiler will implicitly consider any portion of the namespace "above" you to take precedence over class names. In this case, when you say "Addition", the compiler will look for the following items to resolve the name:
A class explicitly identified by a using ... = ... directive.
MyMathLib.Subtraction.Addition namespace.
MyMathLib.Addition namespace.
Addition namespace.
Any classes in the namespaces identified by using statements.
In this case, you're hitting #3 before #4, so you should be able to work around it either by renaming the class or namespace, or by using Yahia's suggestion (#1):
using Addition = MyMathLib.Addition.Addition;
Update 2
After looking at the article you linked to, it sounds like the explicit using statement still won't work. I guess item #1 actually gets evaluated down around item #4 instead. Bummer. You can use an alias to give the class a different name locally:
using Add = MyMathLib.Addition.Addition;
...
var add = new Add();
But the best solution is still probably just to avoid the namespace collision entirely by changing your namespace or class name.
try putting additionally the floowing line into your substraction source
using SomeClass = Addition.SomeClass;
http://msdn.microsoft.com/en-us/library/dfb3cx8s.aspx
http://www.blackwasp.co.uk/NamespaceAliasQualifier.aspx
Sounds like you're in the Subtraction namespace...add this to the top, inside the namespace declaration:
using Addition;
That should do the trick.
I have a webservice project with a class (let's refer to it as webservice.classA).
I have another class project producing a dll which references that class in its own namespace and instantiates an instance of it (lets call the dlls namespace dllnamespace).
In another project I want to access the member in the dll
e.g.
using webservice;
namespace other_project
{
class B
{
classA copy = null;
//....
dllnamespace.dostuff(); // amongst other things instantiates a classA object
//....
copy = dllnamespace.getclassA(); // method to return classA member
The compiler error I get is cannot convert type from dllnamespace.webservice.classA to other_project.webservice.classA
I guess I have a fundamental design flaw but I figure there must be (?) a way to declare/use "webservice.classA" in more than one namespace.
You have a name clash. The supported way of avoiding this (short of not naming your classes the same), is to define a using alias for one of the classes:
using webservice.classA = myWebserviceClassA;
You are right...the design flaw does exist in terms of naming.
Let us assume:
you have a class named
MyClass
the class exists both in namespace- abc.xyz.qwe.tyu.MyClass
and in namespace - sed.qwe.dfg.ert.MyClass
The workaround is -
using NS1 = abc.xyz.qwe.tyu.MyClass;
using NS2 = sed.qwe.dfg.ert.MyClass;
This way you avoid the clash.
Also, helpful to use if you have very long namespaces.
FURTHER REFERENCE : (From MSDN article on using Directive )
The scope of a using directive is
limited to the file in which it
appears.
Create a using alias to make it easier to qualify an identifier to a
namespace or type.
Create a using directive to use the types in a namespace without having to specify the namespace. A using directive does not give you access to any namespaces that are nested in the namespace you specify.
Change the copy definition line to:
dllnamespace.webservice.classA copy = null;
That's just the problem - you cannot have a class in more than one namespace. This is what namespaces were designed for - to prevent classes with the same name written by different people from aliasing. You'll need to decide for one of your namespaces to own that class and in the other one to import it. Alternatively if the dll and the web service are part of the same distributed app then they should use the same namespace.
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).