only for RuBoard - do not distribute or recompile |
A C# program is basically a group of types. These types are defined in files, organized by namespaces, compiled into modules, and then grouped into an assembly.
Generally, these organizational units overlap: an assembly can contain many namespaces, and a namespace can be spread across several assemblies. A module can be part of many assemblies, and an assembly can contain many modules. A source file can contain many namespaces, and a namespace can span many source files. For more information, see Section 3.9 in Chapter 3.
File organization is of almost no significance to the C# compiler: an entire project can be merged into a single .cs file and still compile successfully (preprocessor statements are the only exception to this). However, it's generally tidy to have one type in one file, with a filename that matches the name of the class and a directory name that matches the name of the class's namespace.
Namespace declaration syntax: |
---|
namespace name+a { using-statement* [namespace-declaration | type-declaration]*b } a Dot-delimited. b No delimiters. |
A namespace enables you to group related types into a hierarchical categorization. Generally the first name in a namespace name is the name of your organization, followed by names that group types with finer granularity. For example:
namespace MyCompany.MyProduct.Drawing { class Point {int x, y, z;} delegate void PointInvoker(Point p); }
You may also nest namespace declarations instead of using dots. This example is semantically identical to the previous example:
namespace MyCompany { namespace MyProduct { namespace Drawing { class Point {int x, y, z;} delegate void PointInvoker(Point p); } } }
The complete name of a type includes its namespace name. To use the Point class from another namespace, you may refer to it with its fully qualified name:
namespace TestProject { class Test { static void Main( ) { MyCompany.MyProduct.Drawing.Point x; } } }
The using keyword is a convenient way to avoid using the fully qualified names of types in other namespaces. This example is semantically identical to the previous example:
namespace TestProject { using MyCompany.MyProduct.Drawing; class Test { static void Main( ) { Point x; } } }
Type names must be unique within a namespace. To avoid naming conflicts without having to use fully qualified names, C# allows you to specify an alias for a type or namespace. Here is an example:
using sys = System; // Namespace alias using txt = System.String; // Type alias class Test { static void Main( ) { txt s = "Hello, World!"; sys.Console.WriteLine(s); // Hello, World! sys.Console.WriteLine(s.GetType( )); // System.String } }
The outermost level within which all namespaces and types are implicitly declared is called the global namespace. When a type isn't explicitly declared within a namespace, it can be used without qualification from any other namespace, since it is a member of the global namespace. However, it is always good practice to organize types within logical namespaces
only for RuBoard - do not distribute or recompile |