5.3 C namespaces (Java packages)


5.3 C# namespaces (Java packages)

Like the Java world, we always want to pack our C# classes into neat groups or packages. Besides making things much more organized, one important reason for packaging is to prevent naming conflicts when you are using classes from two separate developers who chose the same names for their classes.

In Java, you package classes using the package keyword. In C#, you use the namespace keyword to do exactly the same thing. In the example below, MyClass has been placed into a namespace called MyNameSpace .

 1: using System; 2:  namespace MyNameSpace{  3:   class MyClass{ 4:     static void Main(string[] args){ 5:     } 6:   } 7:  }  

When you want to access MyClass from another class, you can refer to it by its fully qualified class name (i.e. MyNameSpace.MyClass ). Alternatively, to save some coding ( especially if the namespace name is lengthy), you can use the using keyword. C#'s using keyword is similar to Java's import keyword.

Like Java

  • You can group C# classes into namespaces using the namespace keyword.

  • You can import C# classes using the using keyword.

  • You can have multiple using statements in a C# file, but they must be right at the top of the source file before any class or namespace declaration.

  • It is recommended that you name your namespaces after your company name to prevent namespace conflicts. For example, you could name your namespace Mok.project1 . (Java users recommend that you use the reverse of your company's registered DNS name for your package names.)

  • Both the importing of Java packages and the using of C# namespaces are not recursive. For Java, importing package java.awt does not imply the importing of subpackage java.awt.event . For C#, the statement using System; also does not imply recursive ' usage ' of subnamespaces of System .

  • You cannot use an invalid namespace which the C# compiler cannot find. That's the same as for newer Java compilers. [7] The C# compiler gives a compile time error when it cannot find that namespace referred to in your using statements.

    [7] Older Java compilers generally ignore invalid import statements, but Java 2 SDK 1.4 from Sun actually gives a compilation error when it cannot find all the packages specified in your import statements.

    The statement: using System.FakeNameSpace; results in the compile-time error (if the compiler cannot resolve System.FakeNameSpace ):

    [View full width]
     
    [View full width]
    error CS0246: The type or namespace name 'FakeNameSpace' could not be found (are you graphics/ccc.gif missing a using directive or an assembly reference?)

Unlike Java

  • In Java, java.lang is automatically imported in every Java class. Although C# developers make extensive use of classes from the System namespace, System is not automatically ' used '. The statement ' using System; ' is not implicitly inserted into your C# codes.

  • It is compulsory to envelope all the classes in a particular namespace within curly braces. The statement namespace MyNameSpace; causes a compilation error.

  • In Java, all the classes in a single source file must belong to the same package (if the package statement is used). In a single C# source file, you can have classes placed in different namespaces.

    The following C# source file can compile successfully (compile with the /target:library compiler option, since none of the classes contains a Main method).

     1: // NameSpaceTest.cs  2:  3:  namespace MyNameSpace1{  4:   public class MyClass1{  5:   }  6:   public class MyClass2{  7:   }  8:  }  9: 10:  namespace MyNameSpace2{  11:   public class MyClass1{ 12:   } 13:   public class MyClass2{ 14:   } 15:  }  

    NameSpaceTest.cs defines four classes “ two in the MyNameSpace1 namespace, and another two in the MyNameSpace2 namespace. Note that it is legal to have classes of the same name in the same source file as long as they are defined in separate namespaces. Their fully qualified class names are:

    [View full width]
     
    [View full width]
    MyNameSpace1.MyClass1, MyNameSpace1.MyClass2, MyNameSpace2.MyClass1, and MyNameSpace2. graphics/ccc.gif MyClass2.
  • You cannot include class names in your using statement. In Java, you can import only specific classes in a particular package. For example, the Java statement import java.io.IOException ; imports only the IOException class and excludes all other classes in the java.io package. In C#, you can only 'use' a particular namespace. All the classes in that namespace become automatically 'imported'. If you import a specific class in the namespace, a compile-time error is shown.

    The statement using System.Console ; results in the compile-time error:

    [View full width]
     
    [View full width]
    error CS0138: A using namespace directive can only be applied to namespaces; 'System graphics/ccc.gif .Console' is a class not a namespace
  • Namespace hierarchies do not map into actual directory hierarchies. In Java, if you package your class in com.mok , and compile with the -d flag (using Sun's javac.exe command line compiler), the directories com and com\mok are created automatically. The actual class file is then placed in com\mok . This is not the case for C# “ there is no correlation between directory hierarchy and namespace hierarchy.

  • C# namespaces can be nested. The following source code compiles fine (compile with the /target:library compiler option, since MyClass1 does not contain a Main method):

     1: // NameSpaceTest.cs  2:  3: namespace A{  4:   namespace B{  5:     namespace C{  6:       public class MyClass1{  7:       }  8:     }  9:   } 10: } 

    The fully qualified name of MyClass1 is A.B.C.MyClass1 . You can't do this in Java.

  • The using keyword can be used in a namespace, in which case its scope is only in this particular namespace. It can be used outside any namespace (before any namespace declaration in the source file) and have a scope which spans all namespaces in the source file. Study the example below.

     1: // test.cs  2:  using System  ;  3:  4:  namespace MyNameSpace1{  5:   class MyClass{  6:   }  7:  }  8:  namespace MyNameSpace2{  9:  using MyNameSpace1  ; 10:   class TestClass{ 11:     public static void Main(){ 12:       MyClass c = new MyClass(); 13:     } 14:   } 15:  }  

    The using statement in line 2 has file-wide scope. You can use any class within the System namespace from any class in this file. On the other hand, the using statement in line 9 applies only for classes within MyNameSpace2 . MyClass in line 12 is resolved to MyNameSpace1.MyClass .

5.3.1 A further example

This example demonstrates namespace nesting again, and introduces the /reference option of csc.exe .

The following shows the contents of two source files, Source1.cs and Source2.cs . The ExecuteMe class in Source2.cs contains a Main method which invokes the static DoThis() method of Class2 in Source1.cs . Pay close attention to how the source files are compiled.

 1: // Source1.cs  2:  3: namespace A{  4:   public class Class1{  5:   }  6:  7:   namespace B{  8:     public class Class2{  9:       public static void DoThis(){ 10:         System.Console.WriteLine("doing this"); 11:       } 12:     } 13:   } 14: } 

When compiling Source1.cs , remember to use the /target:library option because Source1.cs does not contain a class which has a Main method:

 c:\expt>csc /target:library Source1.cs 

If compilation succeeds, Source1.dll will be created. Source1.dll contains two classes with the fully qualified class names A.Class1 and A.B.Class2 (note that namespace B is nested within namespace A ).

 1: // Source2.cs  2: using A.B;  3:  4: namespace C{  5:   public class ExecuteMe{  6:     public static void Main(){  7:       Class2.DoThis();  8:     }  9:   } 10: } 

You must compile Source2.cs with the /reference option. The /reference option tells the compiler where to find A.B.Class2 (in this case, Class2 is in the Source1.dll DLL library):

 c:\expt>csc  /reference  :Source1.dll Source2.cs 

If compilation succeeds, Source2.exe will be created. When executed, Source2.exe 's output looks like this:

 c:\expt>Source2 doing this 

If you do not use the /reference option when compiling Source2.cs , the following compile-time error is shown:

[View full width]
 
[View full width]
c:\expt>csc Source2.cs Source2.cs(2,7): error CS0246: The type or namespace name 'A' could not be found(are you graphics/ccc.gif missing a using directive or an assembly reference?)

You can specify multiple DLL files using the /reference option. For example:

 c:\expt>csc /reference:Library1.dll,Library2.dll,Library3.dll SourceToCompile.cs 

5.3.2 Creating your own alias

Another interesting use of the keyword using is to create namespace shortcuts. This example shows how you can create your own namespace shortcuts using the using keyword. Study this short piece of code.

 1  using C  =  System.Console;  //creating alias 2 3 class TestClass{ 4   public static void Main(){ 5  C.WriteLine  ("Hullo Dude!"); 6   } 7 } 

Output:

 c:\expt>test Hullo Dude! 

In this example, we have created an alias called C for System.Console , so that instead of having to type System.Console.WriteLine on line 5, we can use the alias C.WriteLine . A word of good software engineering advice here “ use aliases sparingly and carefully because, like abbreviated identifiers, everybody will start scratching their heads over what ' C ' represents a few weeks down the road.



From Java to C#. A Developers Guide
From Java to C#: A Developers Guide
ISBN: 0321136225
EAN: 2147483647
Year: 2003
Pages: 221
Authors: Heng Ngee Mok

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net