only for RuBoard - do not distribute or recompile Previous Section Next Section

2.6 Organizing Types

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.

2.6.1 Files

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.

2.6.2 Namespaces

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);
}
2.6.2.1 Nesting namespaces

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);
    }
  }
}
2.6.2.2 Using a type with its fully qualified name

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;
    }
  }
}
2.6.2.3 using keyword

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;
    }
  }
}
2.6.2.4 Aliasing types and namespaces

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
  }
}
2.6.2.5 Global namespace

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 Previous Section Next Section