Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 68 additions & 80 deletions docs/csharp/language-reference/keywords/abstract.md
Original file line number Diff line number Diff line change
@@ -1,115 +1,103 @@
---
description: "abstract - C# Reference"
title: "abstract keyword"
ms.date: 07/20/2015
ms.date: 01/21/2026
f1_keywords:
- "abstract"
- "abstract_CSharpKeyword"
helpviewer_keywords:
- "abstract keyword [C#]"
ms.assetid: b0797770-c1f3-4b4d-9441-b9122602a6bb
---
# abstract (C# Reference)

The `abstract` modifier indicates that the thing being modified has a missing or incomplete implementation. The abstract modifier can be used with classes, methods, properties, indexers, and events. Use the `abstract` modifier in a class declaration to indicate that a class is intended only to be a base class of other classes, not instantiated on its own. Members marked as abstract must be implemented by non-abstract classes that derive from the abstract class.
The `abstract` modifier indicates that its target has a missing or incomplete implementation. Use the abstract modifier with classes, methods, properties, indexers, and events. Use the `abstract` modifier in a class declaration to indicate that a class is intended only to be a base class of other classes, not instantiated on its own. Non-abstract classes that derive from the abstract class must implement members marked as abstract.

Abstract classes can contain both abstract members (which have no implementation and must be overridden in derived classes) and fully implemented members (such as regular methods, properties, and constructors). This allows abstract classes to provide common functionality while still requiring derived classes to implement specific abstract members.

## Example 1 - Abstract class with mixed members
[!INCLUDE[csharp-version-note](../includes/initial-version.md)]

Abstract classes can contain both abstract members (which have no implementation and must be overridden in derived classes) and fully implemented members (such as regular methods, properties, and constructors). This feature allows abstract classes to provide common functionality while still requiring derived classes to implement specific abstract members.

> [!NOTE]
> Interface members are `abstract` by default.

## Abstract class with mixed members

The following example demonstrates an abstract class that contains both implemented methods and abstract members:

:::code language="csharp" source="snippets/shared/Abstract.cs" id="snippet1":::

In this example, the `Vehicle` abstract class provides:

- **Implemented members**: `GetInfo()` method, `StartEngine()` method, and constructor - these provide common functionality for all vehicles.
- **Abstract members**: `Move()` method and `MaxSpeed` property - these must be implemented by each specific vehicle type.
- **Implemented members**: `GetInfo()` method, `StartEngine()` method, and constructor - these members provide common functionality for all vehicles.
- **Abstract members**: `Move()` method and `MaxSpeed` property - these members must be implemented by each specific vehicle type.

This design allows the abstract class to provide shared functionality while ensuring that derived classes implement vehicle-specific behavior.

## Example 2

In this example, the class `Square` must provide an implementation of `GetArea` because it derives from `Shape`:

[!code-csharp[csrefKeywordsModifiers#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsModifiers/CS/csrefKeywordsModifiers.cs#1)]

Abstract classes have the following features:

- An abstract class cannot be instantiated.

- An abstract class may contain abstract methods and accessors.

## Concrete class derived from an abstract class

In this example, the class `Square` must provide an implementation of `GetArea` because it derives from `Shape`:

:::code language="csharp" source="snippets/csrefKeywordsModifiers.cs" id="1":::

Abstract classes have the following features:

- You can't create an instance of an abstract class.
- An abstract class can contain abstract methods and accessors.
- An abstract class can also contain implemented methods, properties, fields, and other members that provide functionality to derived classes.

- It is not possible to modify an abstract class with the [sealed](./sealed.md) modifier because the two modifiers have opposite meanings. The `sealed` modifier prevents a class from being inherited and the `abstract` modifier requires a class to be inherited.

- A non-abstract class derived from an abstract class must include actual implementations of all inherited abstract methods and accessors.

Use the `abstract` modifier in a method or property declaration to indicate that the method or property does not contain implementation.

Abstract methods have the following features:

- An abstract method is implicitly a virtual method.

- Abstract method declarations are only permitted in abstract classes.

- Because an abstract method declaration provides no actual implementation, there is no method body; the method declaration simply ends with a semicolon and there are no curly braces ({ }) following the signature. For example:

```csharp
public abstract void MyMethod();
```

The implementation is provided by a method [override](./override.md), which is a member of a non-abstract class.

- It is an error to use the [static](./static.md) or [virtual](./virtual.md) modifiers in an abstract method declaration.

Abstract properties behave like abstract methods, except for the differences in declaration and invocation syntax.

- It is an error to use the `abstract` modifier on a static property.

- An abstract inherited property can be overridden in a derived class by including a property declaration that uses the [override](./override.md) modifier.

For more information about abstract classes, see [Abstract and Sealed Classes and Class Members](../../programming-guide/classes-and-structs/abstract-and-sealed-classes-and-class-members.md).

An abstract class must provide implementation for all interface members.

An abstract class that implements an interface might map the interface methods onto abstract methods. For example:

[!code-csharp[csrefKeywordsModifiers#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsModifiers/CS/csrefKeywordsModifiers.cs#2)]

## Example 3

In this example, the class `DerivedClass` is derived from an abstract class `BaseClass`. The abstract class contains an abstract method, `AbstractMethod`, and two abstract properties, `X` and `Y`.

[!code-csharp[csrefKeywordsModifiers#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsModifiers/CS/csrefKeywordsModifiers.cs#3)]

In the preceding example, if you attempt to instantiate the abstract class by using a statement like this:

```csharp
BaseClass bc = new BaseClass(); // Error
```

You will get an error saying that the compiler cannot create an instance of the abstract class 'BaseClass'.
- You can't use the [`sealed`](./sealed.md) modifier on an abstract class because the two modifiers have opposite meanings. The `sealed` modifier prevents a class from being inherited and the `abstract` modifier requires a class to be inherited.
- A non-abstract class derived from an abstract class must include actual implementations of all inherited abstract methods and accessors.

Use the `abstract` modifier in a method or property declaration to indicate that the method or property doesn't contain implementation.

Abstract methods have the following features:

- An abstract method is implicitly a virtual method.
- Abstract method declarations are only permitted in abstract classes.
- Because an abstract method declaration provides no actual implementation, there's no method body. The method declaration simply ends with a semicolon. For example:

```csharp
public abstract void MyMethod();
```

Nonetheless, it is possible to use an abstract class constructor, as in the example below
The implementation is provided by a method [`override`](./override.md), which is a member of a non-abstract class.

## Example 4
- It's an error to use the [`static`](./static.md) or [`virtual`](./virtual.md) modifiers in an abstract method declaration in a `class` type. You can declare `static abstract` and `static virtual` methods in interfaces.

[!code-csharp[csrefKeywordsModifiers#27](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsModifiers/CS/csrefKeywordsModifiers.cs#27)]
Abstract properties behave like abstract methods, except for the differences in declaration and invocation syntax.

The `Shape` class is declared `abstract`, which means it cannot be instantiated directly. Instead, it serves as a blueprint for other classes.
- It's an error to use the `abstract` modifier on a static property in a `class` type. You can declare `static abstract` or `static virtual` properties in interface declarations.
- An abstract inherited property can be overridden in a derived class by including a property declaration that uses the [`override`](./override.md) modifier.

- Even though you can't create objects of an abstract class, it can still have a constructor. This constructor is typically `protected`, meaning it can only be accessed from derived classes.
For more information about abstract classes, see [Abstract and Sealed Classes and Class Members](../../programming-guide/classes-and-structs/abstract-and-sealed-classes-and-class-members.md).

An abstract class must provide implementation for all interface members. An abstract class that implements an interface might map the interface methods onto abstract methods. For example:

:::code language="csharp" source="snippets/csrefKeywordsModifiers.cs" id="2":::

In the following example, the class `DerivedClass` derives from an abstract class `BaseClass`. The abstract class contains an abstract method, `AbstractMethod`, and two abstract properties, `X` and `Y`.

:::code language="csharp" source="snippets/csrefKeywordsModifiers.cs" id="3":::

In the preceding example, if you attempt to instantiate the abstract class by using a statement like this:

```csharp
BaseClass bc = new BaseClass(); // Error
```

You get an error saying that the compiler can't create an instance of the abstract class 'BaseClass'. Nonetheless, you can use an abstract class constructor, as shown in the following example.

:::code language="csharp" source="snippets/csrefKeywordsModifiers.cs" id="27":::

The `Shape` class is declared `abstract`, which means you can't instantiate it directly. Instead, it serves as a blueprint for other classes.

- Even though you can't create objects of an abstract class, it can still have a constructor. This constructor is typically `protected`, meaning only derived classes can access it.
In this case, the `Shape` constructor takes a `color` parameter and initializes the `Color` property. It also prints a message to the console.
The `public Square(string color, double side) : base(color)` part calls the base class's constructor (`Shape`) and passes the `color` argument to it.
- In the Shape class, the defined constructor takes a color as a parameter `protected Shape(string color)`. This means there's no longer a default parameterless constructor automatically provided by C# thus derived classes must use the `: base(color)` expression to invoke the base constructor. Setting the default value to color `protected Shape(string color="green")` will allow to omit the
`: base(color)` expression in derived classes, still such constructor `protected Shape(string color="green")` will be invoked, setting the color to green.
- In the `Shape` class, the defined constructor takes a color as a parameter `protected Shape(string color)`. This means C# no longer provides a default parameterless constructor automatically. Derived classes must use the `: base(color)` expression to invoke the base constructor. Setting the default value to color `protected Shape(string color="green")` allows omitting the `: base(color)` expression in derived classes. The constructor `protected Shape(string color="green")` sets the color to green.

## C# Language Specification

## C# Language Specification
[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)]

[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)]

## See also

- [virtual](./virtual.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Access Modifiers - C# Reference"
title: "Access Modifiers"
ms.date: 12/15/2025
ms.date: 01/21/2026
helpviewer_keywords:
- "access modifiers [C#]"
---
Expand All @@ -23,6 +23,8 @@ By using these access modifiers, you can specify the following six accessibility
- [`private`](private.md): Access is limited to the containing type.
- [`private protected`](private-protected.md): Access is limited to the containing class or types derived from the containing class within the current assembly.

[!INCLUDE[csharp-version-note](../includes/initial-version.md)]

In addition, a top-level (non-nested) type can use the [`file`](file.md) modifier. The declared type is only visible in the current source file. File scoped types are generally used for source generators. You can't combine the `file` modifier with any access modifier.

This section also introduces the following concepts:
Expand Down
35 changes: 17 additions & 18 deletions docs/csharp/language-reference/keywords/accessibility-domain.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
---
description: "Accessibility Domain - C# Reference"
title: "Accessibility Domain"
ms.date: 07/20/2015
ms.date: 01/21/2026
helpviewer_keywords:
- "accessibility domain [C#]"
ms.assetid: 8af779c1-275b-44be-a864-9edfbca71bcc
---
# Accessibility Domain (C# Reference)

The accessibility domain of a member specifies in which program sections a member can be referenced. If the member is nested within another type, its accessibility domain is determined by both the [accessibility level](./accessibility-levels.md) of the member and the accessibility domain of the immediately containing type.
The accessibility domain of a top-level type is at least the program text of the project that it is declared in. That is, the domain includes all of the source files of this project. The accessibility domain of a nested type is at least the program text of the type in which it is declared. That is, the domain is the type body, which includes all nested types. The accessibility domain of a nested type never exceeds that of the containing type. These concepts are demonstrated in the following example.
## Example

This example contains a top-level type, `T1`, and two nested classes, `M1` and `M2`. The classes contain fields that have different declared accessibilities. In the `Main` method, a comment follows each statement to indicate the accessibility domain of each member. Notice that the statements that try to reference the inaccessible members are commented out. If you want to see the compiler errors caused by referencing an inaccessible member, remove the comments one at a time.
[!code-csharp[csrefKeywordsModifiers#4](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsModifiers/CS/csrefKeywordsModifiers.cs#4)]
## C# Language Specification

[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)]
# Accessibility domain (C# reference)

The accessibility domain of a member specifies the program sections where you can reference that member. If the member is nested within another type, both the [accessibility level](./accessibility-levels.md) of the member and the accessibility domain of the immediately containing type determine its accessibility domain.

[!INCLUDE[csharp-version-note](../includes/initial-version.md)]

The accessibility domain of a top-level type always includes at least the program text of the project where you declare it. In other words, the domain includes all source files in the project. The accessibility domain of a nested type always includes at least the program text of the type where you declare it. In other words, the domain is the type body, which includes all nested types. The accessibility domain of a nested type never exceeds that of the containing type. The following example demonstrates these concepts.

This example contains a top-level type, `T1`, and two nested classes, `M1` and `M2`. The classes contain fields that have different declared accessibilities. In the `Main` method, a comment follows each statement to indicate the accessibility domain of each member. The statements that try to reference the inaccessible members are commented out. If you want to see the compiler errors caused by referencing an inaccessible member, remove the comments one at a time.

:::code language="csharp" source="snippets/csrefKeywordsModifiers.cs" id="4":::

## C# Language Specification

[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)]

## See also

- [C# Keywords](./index.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Accessibility Levels - C# Reference"
title: "Accessibility Levels"
ms.date: 12/15/2025
ms.date: 01/21/2026
helpviewer_keywords:
- "access modifiers [C#], accessibility levels"
- "accessibility levels"
Expand All @@ -10,14 +10,14 @@ helpviewer_keywords:

Use the access modifiers `public`, `protected`, `internal`, or `private` to specify one of the following declared accessibility levels for members.

| Declared accessibility | Meaning |
|-----------------------------------------------|-------------------------------------------------------------|
| [`public`](public.md) | Access isn't restricted. |
| [`protected`](protected.md) | Access is limited to the containing class or types derived from the containing class. |
| [`internal`](internal.md) | Access is limited to the current assembly. |
| [`protected internal`](protected-internal.md) | Access is limited to the current assembly or types derived from the containing class. |
| [`private`](private.md) | Access is limited to the containing type. |
| [`private protected`](private-protected.md) | Access is limited to the containing class or types derived from the containing class within the current assembly. |
- [`public`](public.md): Access isn't restricted.
- [`protected`](protected.md): Access is limited to the containing class or types derived from the containing class.
- [`internal`](internal.md): Access is limited to the current assembly.
- [`protected internal`](protected-internal.md): Access is limited to the current assembly or types derived from the containing class.
- [`private`](private.md): Access is limited to the containing type.
- [`private protected`](private-protected.md): Access is limited to the containing class or types derived from the containing class within the current assembly.

[!INCLUDE[csharp-version-note](../includes/initial-version.md)]

Top-level (non-nested) types can use the [file](../../language-reference/keywords/file.md) modifier. The `file` modifier restricts access to code in the same source file. You can't combine the `file` modifier with any access modifier.

Expand Down
Loading
Loading