ECMA-334 C# Language Specification

10.3: Declarations

Declarations in a C# program define the constituent elements of the program. C# programs are organized using namespaces (16), which can contain type declarations and nested namespace declarations. Type declarations (16.5) are used to define classes (17), structs (18), interfaces (20), enums (21), and delegates (22). The kinds of members permitted in a type declaration depend on the form of the type declaration. For instance, class declarations can contain declarations for constants (17.3), fields (17.4), methods (17.5), properties (17.6), events (17.7), indexers (17.8), operators (17.9), instance constructors (17.10), destructors (17.12), static constructors (17.11), and nested types.

A declaration defines a name in the declaration space to which the declaration belongs. Except for overloaded members (10.6), it is a compile-time error to have two or more declarations that introduce members with the same name in a declaration space. However, no diagnostic is required if the declaration space is a namespace for the global declaration space and the conflicting declarations are in separate programs. It is never possible for a declaration space to contain different kinds of members with the same name. [Example: For example, a declaration space can never contain a field and a method by the same name. end example]

There are several different types of declaration spaces, as described in the following.

The textual order in which names are declared is generally of no significance. In particular, textual order is not significant for the declaration and use of namespaces, constants, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors, and types. Declaration order is significant in the following ways:

[Example: The declaration space of a namespace is "open ended", and two namespace declarations with the same fully qualified name contribute to the same declaration space. For example
namespace Megacorp.Data  
{  
   class Customer  
   {  
      ...  
   }  
}  
namespace Megacorp.Data  
{  
   class Order  
   {  
      ...  
   }  
}  

The two namespace declarations above contribute to the same declaration space, in this case declaring two classes with the fully qualified names Megacorp.Data.Customer and Megacorp.Data.Order. Because the two declarations contribute to the same declaration space, it would have caused a compile-time error if each contained a declaration of a class with the same name. end example]

[Note: As specified above, the declaration space of a block includes any nested blocks. Thus, in the following example, the F and G methods result in a compile-time error because the name i is declared in the outer block and cannot be redeclared in the inner block. However, the H and I methods are valid since the two i's are declared in separate non-nested blocks.
class A  
{  
   void F() {  
      int i = 0;  
      if (true) {  
         int i = 1;        
      }  
   }  
   void G() {  
      if (true) {  
         int i = 0;  
      }  
      int i = 1;          
   }  
   void H() {  
      if (true) {  
         int i = 0;  
      }  
      if (true) {  
         int i = 1;  
      }  
   }  
   void I() {  
      for (int i = 0; i < 10; i++)  
      H();  
      for (int i = 0; i < 10; i++)  
      H();  
   }  
}  
end note]