- •Foreword
- •Introduction
- •Scope
- •Conformance
- •Normative references
- •Definitions
- •Notational conventions
- •Acronyms and abbreviations
- •General description
- •Language overview
- •Getting started
- •Types
- •Predefined types
- •Conversions
- •Array types
- •Type system unification
- •Variables and parameters
- •Automatic memory management
- •Expressions
- •Statements
- •Classes
- •Constants
- •Fields
- •Methods
- •Properties
- •Events
- •Operators
- •Indexers
- •Instance constructors
- •Destructors
- •Static constructors
- •Inheritance
- •Static classes
- •Partial type declarations
- •Structs
- •Interfaces
- •Delegates
- •Enums
- •Namespaces and assemblies
- •Versioning
- •Extern Aliases
- •Attributes
- •Generics
- •Why generics?
- •Creating and consuming generics
- •Multiple type parameters
- •Constraints
- •Generic methods
- •Anonymous methods
- •Iterators
- •Lexical structure
- •Programs
- •Grammars
- •Lexical grammar
- •Syntactic grammar
- •Grammar ambiguities
- •Lexical analysis
- •Line terminators
- •Comments
- •White space
- •Tokens
- •Unicode escape sequences
- •Identifiers
- •Keywords
- •Literals
- •Boolean literals
- •Integer literals
- •Real literals
- •Character literals
- •String literals
- •The null literal
- •Operators and punctuators
- •Pre-processing directives
- •Conditional compilation symbols
- •Pre-processing expressions
- •Declaration directives
- •Conditional compilation directives
- •Diagnostic directives
- •Region control
- •Line directives
- •Pragma directives
- •Basic concepts
- •Application startup
- •Application termination
- •Declarations
- •Members
- •Namespace members
- •Struct members
- •Enumeration members
- •Class members
- •Interface members
- •Array members
- •Delegate members
- •Member access
- •Declared accessibility
- •Accessibility domains
- •Protected access for instance members
- •Accessibility constraints
- •Signatures and overloading
- •Scopes
- •Name hiding
- •Hiding through nesting
- •Hiding through inheritance
- •Namespace and type names
- •Unqualified name
- •Fully qualified names
- •Automatic memory management
- •Execution order
- •Types
- •Value types
- •The System.ValueType type
- •Default constructors
- •Struct types
- •Simple types
- •Integral types
- •Floating point types
- •The decimal type
- •The bool type
- •Enumeration types
- •Reference types
- •Class types
- •The object type
- •The string type
- •Interface types
- •Array types
- •Delegate types
- •Boxing and unboxing
- •Boxing conversions
- •Unboxing conversions
- •Variables
- •Variable categories
- •Static variables
- •Instance variables
- •Instance variables in classes
- •Instance variables in structs
- •Array elements
- •Value parameters
- •Reference parameters
- •Output parameters
- •Local variables
- •Default values
- •Definite assignment
- •Initially assigned variables
- •Initially unassigned variables
- •Precise rules for determining definite assignment
- •General rules for statements
- •Block statements, checked, and unchecked statements
- •Expression statements
- •Declaration statements
- •If statements
- •Switch statements
- •While statements
- •Do statements
- •For statements
- •Break, continue, and goto statements
- •Throw statements
- •Return statements
- •Try-catch statements
- •Try-finally statements
- •Try-catch-finally statements
- •Foreach statements
- •Using statements
- •Lock statements
- •General rules for simple expressions
- •General rules for expressions with embedded expressions
- •Invocation expressions and object creation expressions
- •Simple assignment expressions
- •&& expressions
- •|| expressions
- •! expressions
- •?: expressions
- •Anonymous method expressions
- •Yield statements
- •Variable references
- •Atomicity of variable references
- •Conversions
- •Implicit conversions
- •Identity conversion
- •Implicit numeric conversions
- •Implicit enumeration conversions
- •Implicit reference conversions
- •Boxing conversions
- •Implicit type parameter conversions
- •Implicit constant expression conversions
- •User-defined implicit conversions
- •Explicit conversions
- •Explicit numeric conversions
- •Explicit enumeration conversions
- •Explicit reference conversions
- •Unboxing conversions
- •User-defined explicit conversions
- •Standard conversions
- •Standard implicit conversions
- •Standard explicit conversions
- •User-defined conversions
- •Permitted user-defined conversions
- •Evaluation of user-defined conversions
- •User-defined implicit conversions
- •User-defined explicit conversions
- •Anonymous method conversions
- •Method group conversions
- •Expressions
- •Expression classifications
- •Values of expressions
- •Operators
- •Operator precedence and associativity
- •Operator overloading
- •Unary operator overload resolution
- •Binary operator overload resolution
- •Candidate user-defined operators
- •Numeric promotions
- •Unary numeric promotions
- •Binary numeric promotions
- •Member lookup
- •Base types
- •Function members
- •Argument lists
- •Overload resolution
- •Applicable function member
- •Better function member
- •Better conversion
- •Function member invocation
- •Invocations on boxed instances
- •Primary expressions
- •Literals
- •Simple names
- •Invariant meaning in blocks
- •Parenthesized expressions
- •Member access
- •Identical simple names and type names
- •Invocation expressions
- •Method invocations
- •Delegate invocations
- •Element access
- •Array access
- •Indexer access
- •This access
- •Base access
- •Postfix increment and decrement operators
- •The new operator
- •Object creation expressions
- •Array creation expressions
- •Delegate creation expressions
- •The typeof operator
- •The checked and unchecked operators
- •Default value expression
- •Anonymous methods
- •Anonymous method signatures
- •Anonymous method blocks
- •Outer variables
- •Captured outer variables
- •Instantiation of local variables
- •Anonymous method evaluation
- •Implementation example
- •Unary expressions
- •Unary plus operator
- •Unary minus operator
- •Logical negation operator
- •Bitwise complement operator
- •Prefix increment and decrement operators
- •Cast expressions
- •Arithmetic operators
- •Multiplication operator
- •Division operator
- •Remainder operator
- •Addition operator
- •Subtraction operator
- •Shift operators
- •Relational and type-testing operators
- •Integer comparison operators
- •Floating-point comparison operators
- •Decimal comparison operators
- •Boolean equality operators
- •Enumeration comparison operators
- •Reference type equality operators
- •String equality operators
- •Delegate equality operators
- •The is operator
- •The as operator
- •Logical operators
- •Integer logical operators
- •Enumeration logical operators
- •Boolean logical operators
- •Conditional logical operators
- •Boolean conditional logical operators
- •User-defined conditional logical operators
- •Conditional operator
- •Assignment operators
- •Simple assignment
- •Compound assignment
- •Event assignment
- •Expression
- •Constant expressions
- •Boolean expressions
- •Statements
- •End points and reachability
- •Blocks
- •Statement lists
- •The empty statement
- •Labeled statements
- •Declaration statements
- •Local variable declarations
- •Local constant declarations
- •Expression statements
- •Selection statements
- •The if statement
- •The switch statement
- •Iteration statements
- •The while statement
- •The do statement
- •The for statement
- •The foreach statement
- •Jump statements
- •The break statement
- •The continue statement
- •The goto statement
- •The return statement
- •The throw statement
- •The try statement
- •The checked and unchecked statements
- •The lock statement
- •The using statement
- •The yield statement
- •Namespaces
- •Compilation units
- •Namespace declarations
- •Extern alias directives
- •Using directives
- •Using alias directives
- •Using namespace directives
- •Namespace members
- •Type declarations
- •Qualified alias member
- •Classes
- •Class declarations
- •Class modifiers
- •Abstract classes
- •Sealed classes
- •Static classes
- •Class base specification
- •Base classes
- •Interface implementations
- •Class body
- •Partial declarations
- •Class members
- •Inheritance
- •The new modifier
- •Access modifiers
- •Constituent types
- •Static and instance members
- •Nested types
- •Fully qualified name
- •Declared accessibility
- •Hiding
- •this access
- •Reserved member names
- •Member names reserved for properties
- •Member names reserved for events
- •Member names reserved for indexers
- •Member names reserved for destructors
- •Constants
- •Fields
- •Static and instance fields
- •Readonly fields
- •Using static readonly fields for constants
- •Versioning of constants and static readonly fields
- •Volatile fields
- •Field initialization
- •Variable initializers
- •Static field initialization
- •Instance field initialization
- •Methods
- •Method parameters
- •Value parameters
- •Reference parameters
- •Output parameters
- •Parameter arrays
- •Static and instance methods
- •Virtual methods
- •Override methods
- •Sealed methods
- •Abstract methods
- •External methods
- •Method body
- •Method overloading
- •Properties
- •Static and instance properties
- •Accessors
- •Virtual, sealed, override, and abstract accessors
- •Events
- •Field-like events
- •Event accessors
- •Static and instance events
- •Virtual, sealed, override, and abstract accessors
- •Indexers
- •Indexer overloading
- •Operators
- •Unary operators
- •Binary operators
- •Conversion operators
- •Instance constructors
- •Constructor initializers
- •Instance variable initializers
- •Constructor execution
- •Default constructors
- •Private constructors
- •Optional instance constructor parameters
- •Static constructors
- •Destructors
- •Structs
- •Struct declarations
- •Struct modifiers
- •Struct interfaces
- •Struct body
- •Struct members
- •Class and struct differences
- •Value semantics
- •Inheritance
- •Assignment
- •Default values
- •Boxing and unboxing
- •Meaning of this
- •Field initializers
- •Constructors
- •Destructors
- •Static constructors
- •Struct examples
- •Database integer type
- •Database boolean type
- •Arrays
- •Array types
- •The System.Array type
- •Array creation
- •Array element access
- •Array members
- •Array covariance
- •Arrays and the generic IList interface
- •Array initializers
- •Interfaces
- •Interface declarations
- •Interface modifiers
- •Base interfaces
- •Interface body
- •Interface members
- •Interface methods
- •Interface properties
- •Interface events
- •Interface indexers
- •Interface member access
- •Fully qualified interface member names
- •Interface implementations
- •Explicit interface member implementations
- •Interface mapping
- •Interface implementation inheritance
- •Interface re-implementation
- •Abstract classes and interfaces
- •Enums
- •Enum declarations
- •Enum modifiers
- •Enum members
- •The System.Enum type
- •Enum values and operations
- •Delegates
- •Delegate declarations
- •Delegate instantiation
- •Delegate invocation
- •Exceptions
- •Causes of exceptions
- •The System.Exception class
- •How exceptions are handled
- •Common Exception Classes
- •Attributes
- •Attribute classes
- •Attribute usage
- •Positional and named parameters
- •Attribute parameter types
- •Attribute specification
- •Attribute instances
- •Compilation of an attribute
- •Run-time retrieval of an attribute instance
- •Reserved attributes
- •The AttributeUsage attribute
- •The Conditional attribute
- •Conditional Methods
- •Conditional Attribute Classes
- •The Obsolete attribute
- •Unsafe code
- •Unsafe contexts
- •Pointer types
- •Fixed and moveable variables
- •Pointer conversions
- •Pointers in expressions
- •Pointer indirection
- •Pointer member access
- •Pointer element access
- •The address-of operator
- •Pointer increment and decrement
- •Pointer arithmetic
- •Pointer comparison
- •The sizeof operator
- •The fixed statement
- •Stack allocation
- •Dynamic memory allocation
- •Generics
- •Generic class declarations
- •Type parameters
- •The instance type
- •Members of generic classes
- •Static fields in generic classes
- •Static constructors in generic classes
- •Accessing protected members
- •Overloading in generic classes
- •Parameter array methods and type parameters
- •Overriding and generic classes
- •Operators in generic classes
- •Nested types in generic classes
- •Generic struct declarations
- •Generic interface declarations
- •Uniqueness of implemented interfaces
- •Explicit interface member implementations
- •Generic delegate declarations
- •Constructed types
- •Type arguments
- •Open and closed types
- •Base classes and interfaces of a constructed type
- •Members of a constructed type
- •Accessibility of a constructed type
- •Conversions
- •Using alias directives
- •Generic methods
- •Generic method signatures
- •Virtual generic methods
- •Calling generic methods
- •Inference of type arguments
- •Using a generic method with a delegate
- •Constraints
- •Satisfying constraints
- •Member lookup on type parameters
- •Type parameters and boxing
- •Conversions involving type parameters
- •Iterators
- •Iterator blocks
- •Enumerator interfaces
- •Enumerable interfaces
- •Yield type
- •This access
- •Enumerator objects
- •The MoveNext method
- •The Current property
- •The Dispose method
- •Enumerable objects
- •The GetEnumerator method
- •Implementation example
- •Lexical grammar
- •Line terminators
- •White space
- •Comments
- •Unicode character escape sequences
- •Identifiers
- •Keywords
- •Literals
- •Operators and punctuators
- •Pre-processing directives
- •Syntactic grammar
- •Basic concepts
- •Types
- •Expressions
- •Statements
- •Classes
- •Structs
- •Arrays
- •Interfaces
- •Enums
- •Delegates
- •Attributes
- •Generics
- •Grammar extensions for unsafe code
- •Undefined behavior
- •Implementation-defined behavior
- •Unspecified behavior
- •Other Issues
- •Capitalization styles
- •Pascal casing
- •Camel casing
- •All uppercase
- •Capitalization summary
- •Word choice
- •Namespaces
- •Classes
- •Interfaces
- •Enums
- •Static fields
- •Parameters
- •Methods
- •Properties
- •Events
- •Case sensitivity
- •Avoiding type name confusion
- •Documentation Comments
- •Introduction
- •Recommended tags
- •<code>
- •<example>
- •<exception>
- •<list>
- •<para>
- •<param>
- •<paramref>
- •<permission>
- •<remarks>
- •<returns>
- •<seealso>
- •<summary>
- •<value>
- •Processing the documentation file
- •ID string format
- •ID string examples
- •An example
- •C# source code
- •Resulting XML
|
Chapter 17 Classes |
1 |
public void SubmitOrder(Order orderSubmitted) { |
2 |
orders.Add(orderSubmitted); |
3 |
} |
4 |
public bool HasOutstandingOrders() { |
5 |
return orders.Count > 0; |
6}
7}
8end example]
9The handling of attributes specified on the type or type parameters of different parts of a partial declaration
10is discussed in §24.2
1117.2 Class members
12The members of a class consist of the members introduced by its class-member-declarations and the
13members inherited from the direct base class.
14class-member-declarations:
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class-member-declaration
class-member-declarations class-member-declaration
class-member-declaration: constant-declaration field-declaration method-declaration property-declaration event-declaration indexer-declaration operator-declaration constructor-declaration destructor-declaration static-constructor-declaration type-declaration
29The members of a class are divided into the following categories:
30• Constants, which represent constant values associated with that class (§17.3).
31• Fields, which are the variables of that class (§17.4).
32• Methods, both non-generic and generic, which implement the computations and actions that can be
33performed by that class (§17.5, §26.6).
34• Properties, which define named characteristics and the actions associated with reading and writing those
35characteristics (§17.6).
36• Events, which define notifications that can be generated by that class (§17.7).
37• Indexers, which permit instances of that class to be indexed in the same way as arrays (§17.8).
38• Operators, which define the expression operators that can be applied to instances of that class (§17.9).
39• Instance constructors, which implement the actions required to initialize instances of that class (§17.10)
40• Destructors, which implement the actions to be performed before instances of that class are permanently
41discarded (§17.12).
42• Static constructors, which implement the actions required to initialize that class itself (§17.11).
43• Types, which represent the types that are local to that class (§16.6).
44Members that can contain executable code are collectively known as the function members of the class. The
45function members of a class are the methods, properties, events, indexers, operators, instance constructors,
46destructors, and static constructors of that class.
261
C# LANGUAGE SPECIFICATION
1A class-declaration creates a new declaration space (§10.3), and the type-parameters and the class-member-
2declarations immediately contained by the class-declaration introduce new members into this declaration
3space. The following rules apply to class-member-declarations:
4• Instance constructors, destructors, and static constructors shall have the same name as the immediately
5enclosing class. All other members shall have names that differ from the name of the immediately
6enclosing class.
7• The name of a type parameter in the type-parameter-list of a class declaration shall differ from the
8names of all other type parameters in the same type-parameter-list and shall differ from the name of the
9class and the names of all members of the class.
10• The name of a type must differ from the names of all non-type members declared in the same class. If
11two or more type declarations share the same fully qualified name, the declarations must have the partial
12modifier (§17.1.4) and these declarations combine to define a single type. [Note: Since the fully
13qualified name of a type declaration encodes the number of type parameters, two distinct types may
14share the same name as long as they have different number of type parameters. end note]
15• The name of a constant, field, property, or event shall differ from the names of all other members
16declared in the same class.
17• The name of a method shall differ from the names of all other non-methods declared in the same class.
18In addition, the signature (§10.6) of a method shall differ from the signatures of all other methods
19declared in the same class, and two methods declared in the same class shall not have signatures that
20differ solely by ref and out.
21• The signature of an instance constructor shall differ from the signatures of all other instance constructors
22declared in the same class, and two constructors declared in the same class shall not have signatures that
23differ solely by ref and out.
24• The signature of an indexer shall differ from the signatures of all other indexers declared in the same
25class.
26• The signature of an operator shall differ from the signatures of all other operators declared in the same
27class.
28The inherited members of a class (§17.2.1) are not part of the declaration space of a class. [Note: Thus, a
29derived class is allowed to declare a member with the same name or signature as an inherited member
30(which in effect hides the inherited member). end note]
31The set of members of a type declared in multiple parts (§17.1.4) is the union of the members declared in
32each part. The bodies of all parts of the type declaration share the same declaration space (§10.3), and the
33scope of each member (§10.7) extends to the bodies of all the parts. The accessibility domain of any member
34always includes all the parts of the enclosing type; a private member declared in one part is freely
35accessible from another part. It is a compile-time error to declare the same member in more than one part of
36the type, unless that member is a type having the partial modifier. [Example:
37partial class A
38{
39 |
int x; |
// Error, cannot declare x more than once |
40 |
partial class Inner |
// Ok, Inner is a partial type |
41 |
{ |
|
42 |
int y; |
|
43}
44}
45partial class A
46{
47 |
int x; |
// Error, cannot declare x more than once |
262
|
Chapter 17 Classes |
|
1 |
partial class Inner |
// Ok, Inner is a partial type |
2 |
{ |
|
3 |
int z; |
|
4}
5}
6end example]
7The ordering of members within a type declared in multiple parts is undefined. [Note: Although the ordering
8of members within a type is not significant to C# code, it may be significant when interfacing with other
9languages and environments. end note]
1017.2.1 Inheritance
11A class inherits the members of its direct base class. Inheritance means that a class implicitly contains all
12members of its direct base class, except for the instance constructors, destructors, and static constructors of
13the base class. Some important aspects of inheritance are:
14• Inheritance is transitive. If C is derived from B, and B is derived from A, then C inherits the members
15declared in A as well as the members declared in B.
16• A derived class extends its direct base class. A derived class can add new members to those it inherits,
17but it cannot remove the definition of an inherited member.
18• Instance constructors, destructors, and static constructors are not inherited, but all other members are,
19regardless of their declared accessibility (§10.5). However, depending on their declared accessibility,
20inherited members might not be accessible in a derived class.
21• A derived class can hide (§10.7.1.2) inherited members by declaring new members with the same name
22or signature. However, hiding an inherited member does not remove that member—it merely means that
23member will not be found by member lookup within the derived class.
24• An instance of a class contains a set of all instance fields declared in the class and its base classes, and
25an implicit conversion (§13.1.4) exists from a derived class type to any of its base class types. Thus, a
26reference to an instance of some derived class can be treated as a reference to an instance of any of its
27base classes.
28• A class can declare virtual methods, properties, indexers, and events, and derived classes can override
29the implementation of these function members. This enables classes to exhibit polymorphic behavior
30wherein the actions performed by a function member invocation varies depending on the run-time type
31of the instance through which that function member is invoked.
32• Members inherited from a constructed generic type are inherited after type substitution. That is, any
33constituent types in the member have the base class declaration’s type parameters replaced with the
34corresponding type arguments used in the class-base specification.
35[Example: In the example:
36class A<S>
37{
38public S field;
39}
40class B<T> : A<T[]>
41{
42 |
// inherited: public T[] x; |
43public A<T> Meth(T t) { … }
44}
45class C : B<string>
46{
47 |
// inherited: public string[] x; |
48// inherited: public A<string> Meth(string t);
49}
263
C# LANGUAGE SPECIFICATION
1class B<T> inherits member field from A<S> after type parameter S is replaced with the type argument
2T[]. Similarly class C inherits the members of B<T> (including the inherited member field) after type
3parameter T is replaced with the type argument string. end example]
417.2.2 The new modifier
5A class-member-declaration is permitted to declare a member with the same name or signature as an
6inherited member. When this occurs, the derived class member is said to hide the base class member. See
7§10.7.1.2 for a precise specification of when a member hides an inherited member.
8An inherited member M is considered to be available if M is accessible and there is no other inherited
9accessible member N that already hides M.
10Hiding an available inherited member is not considered an error, but it does cause the compiler to issue a
11warning. To suppress the warning, the declaration of the derived class member can include a new modifier
12to indicate that the derived member is intended to hide the base member. If one or more parts of a partial
13declaration §17.1.4) of a nested type include the new modifier, no warning is issued if the nested type hides
14an available inherited member.
15If a new modifier is included in a declaration that doesn’t hide an available inherited member, a warning to
16that effect is issued.
1717.2.3 Access modifiers
18A class-member-declaration can have any one of the five possible kinds of declared accessibility (§10.5.1):
19public, protected internal, protected, internal, or private. Except for the protected
20internal combination, it is a compile-time error to specify more than one access modifier. When a class-
21member-declaration does not include any access modifiers, private is assumed.
2217.2.4 Constituent types
23Types that are used in the declaration of a member are called the constituent types of that member. Possible
24constituent types are the type of a constant, field, property, event, or indexer, the return type of a method or
25operator, and the parameter types of a method, indexer, operator, or instance constructor. The constituent
26types of a member shall be at least as accessible as that member itself (§10.5.4).
2717.2.5 Static and instance members
28Members of a class are either static members or instance members. [Note: Generally speaking, it is useful
29to think of static members as belonging to classes and instance members as belonging to objects (instances
30of classes). end note]
31When a field, method, property, event, operator, or constructor declaration includes a static modifier, it
32declares a static member. In addition, a constant or type declaration implicitly declares a static member.
33Static members have the following characteristics:
34• When a static member is referenced in a member-access (§14.5.4) of the form E.M, E shall denote a type
35that has a member M. It is a compile-time error for E to denote an instance.
36• A static field in a non-generic class identifies exactly one storage location. No matter how many
37instances of a non-generic class are created, there is only ever one copy of a static field. Each distinct
38closed constructed type (§26.5.2) has its own set of static fields, regardless of the number of instances of
39the closed constructed type.
40• A static function member (method, property, event, operator, or constructor) does not operate on a
41specific instance, and it is a compile-time error to refer to this in such a function member.
42When a field, method, property, event, indexer, constructor, or destructor declaration does not include a
43static modifier, it declares an instance member. (An instance member is sometimes called a non-static
44member.) Instance members have the following characteristics:
264
