A class-declaration is a type-declaration (§16.5) that declares a new class.
class-declaration:
attributesopt class-modifiersopt class identifier class-baseopt class-body
;opt
A class-declaration consists of an optional set of attributes (§24),
followed by an optional set of class-modifiers
(§17.1.1), followed by the keyword class and an identifier that names the
class, followed by an optional classbase
specification (§17.1.2), followed by a class-body (§17.1.3), optionally
followed by a semicolon.
17.1.1 Class modifiers
A class-declaration may optionally include a sequence of class modifiers:
class-modifiers:
class-modifier
class-modifiers class-modifier
class-modifier:
new
public
protected
internal
private
abstract
sealed
It is a compile-time error for the same modifier to appear multiple times
in a class declaration.
The new modifier is permitted on nested classes. It specifies that the
class hides an inherited member by the same
name, as described in §10.2.2. It is a compile-time error for the new
modifier to appear on a class declaration that
is not a nested class declaration.
The public, protected, internal, and private modifiers control the
accessibility of the class. Depending
on the context in which the class declaration occurs, some of these
modifiers may not be permitted (§10.5.1).
The abstract and sealed modifiers are discussed in the following sections.
17.1.1.1 Abstract classes
The abstract modifier is used to indicate that a class is incomplete and
that it is intended to be used only as a
base class. An abstract class differs from a non-abstract class in the
following ways:
? An abstract class cannot be instantiated directly, and it is a
compile-time error to use the new operator on an
abstract class. While it is possible to have variables and values whose
compile-time types are abstract, such
variables and values will necessarily either be null or contain references
to instances of non-abstract classes
derived from the abstract types.
? An abstract class is permitted (but not required) to contain abstract
members.
C# LANGUAGE SPECIFICATION
210
? An abstract class cannot be sealed.
When a non-abstract class is derived from an abstract class, the
non-abstract class must include actual
implementations of all inherited abstract members, thereby overriding those
abstract members. [Example: In the
example
abstract class A
{
public abstract void F();
}
abstract class B: A
{
public void G() {}
}
class C: B
{
public override void F() {
// actual implementation of F
}
}
the abstract class A introduces an abstract method F. Class B introduces an
additional method G, but since it
doesn?t provide an implementation of F, B must also be declared abstract.
Class C overrides F and provides an
actual implementation. Since there are no abstract members in C, C is
permitted (but not required) to be nonabstract.
end example]
17.1.1.2 Sealed classes
The sealed modifier is used to prevent derivation from a class. A
compile-time error occurs if a sealed class is
specified as the base class of another class.
A sealed class cannot also be an abstract class.
[Note: The sealed modifier is primarily used to prevent unintended
derivation, but it also enables certain runtime
optimizations. In particular, because a sealed class is known to never have
any derived classes, it is possible
to transform virtual function member invocations on sealed class instances
into non-virtual invocations. end note]
17.1.2 Class base specification
A class declaration may include a class-base specification, which defines
the direct base class of the class and the
interfaces (§20) implemented by the class.
class-base:
: class-type
: interface-type-list
: class-type , interface-type-list
interface-type-list:
interface-type
interface-type-list , interface-type
17.1.2.1 Base classes
When a class-type is included in the class-base, it specifies the direct
base class of the class being declared. If a
class declaration has no class-base, or if the class-base lists only
interface types, the direct base class is assumed
to be object. A class inherits members from its direct base class, as
described in §17.2.1.
[Example: In the example
class A {}
class B: A {}
class A is said to be the direct base class of B, and B is said to be
derived from A. Since A does not explicitly
specify a direct base class, its direct base class is implicitly object.
end example]
Chapter 17 Classes
211
The direct base class of a class type must be at least as accessible as the
class type itself (§10.5.4). For example, it
is a compile-time error for a public class to derive from a private or
internal class.
The direct base class of a class type must not be any of the following
types: System.Array,
System.Delegate, System.Enum, or System.ValueType.
The base classes of a class are the direct base class and its base classes.
In other words, the set of base classes is
the transitive closure of the direct base class relationship. [Note:
Referring to the example above, the base classes
of B are A and object. end note]
Except for class object, every class has exactly one direct base class. The
object class has no direct base class
and is the ultimate base class of all other classes.
When a class B derives from a class A, it is a compile-time error for A to
depend on B. A class directly depends on
its direct base class (if any) and directly depends on the class within
which it is immediately nested (if any).
Given this definition, the complete set of classes upon which a class
depends is the transitive closure of the
directly depends on relationship.
[Example: The example
class A: B {}
class B: C {}
class C: A {}
is in error because the classes circularly depend on themselves. Likewise,
the example
class A: B.C {}
class B: A
{
public class C {}
}
results in a compile-time error because A depends on B.C (its direct base
class), which depends on B (its
immediately enclosing class), which circularly depends on A. end example]
A class does not depend on the classes that are nested within it. [Example:
In the example
class A
{
class B: A {}
}
B depends on A (because A is both its direct base class and its immediately
enclosing class), but A does not
depend on B (since B is neither a base class nor an enclosing class of A).
Thus, the example is valid. end example]
It is not possible to derive from a sealed class. [Example: In the example
sealed class A {}
class B: A {} // Error, cannot derive from a sealed class
class B results in a compile-time error because it attempts to derive from
the sealed class A. end example]
17.1.2.2 Interface implementations
A class-base specification may include a list of interface types, in which
case the class is said to implement the
given interface types. Interface implementations are discussed further in §2
0.4.
17.1.3 Class body
The class-body of a class defines the members of that class.
class-body:
{ class-member-declarationsopt }