Skip to content

ProgrammingGuideClassesAndStructsFinalizers #26101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
4 changes: 4 additions & 0 deletions .openpublishing.redirection.json
Original file line number Diff line number Diff line change
Expand Up @@ -1904,6 +1904,10 @@
"source_path": "docs/csharp/programming-guide/classes-and-structs/classes.md",
"redirect_url": "/dotnet/csharp/fundamentals/types/classes"
},
{
"source_path": "docs/csharp/programming-guide/classes-and-structs/destructors.md",
"redirect_url": "/dotnet/csharp/programming-guide/classes-and-structs/finalizers"
},
{
"source_path": "docs/csharp/programming-guide/classes-and-structs/how-to-access-a-collection-class-with-foreach.md",
"redirect_url": "/dotnet/csharp/language-reference/keywords/foreach-in"
Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/fundamentals/object-oriented/objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ For more information:

- [Classes](../types/classes.md)
- [Constructors](../../programming-guide/classes-and-structs/constructors.md)
- [Finalizers](../../programming-guide/classes-and-structs/destructors.md)
- [Finalizers](../../programming-guide/classes-and-structs/finalizers.md)
- [Events](../../programming-guide/events/index.md)
- [object](../../language-reference/builtin-types/reference-types.md)
- [Inheritance](./inheritance.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/fundamentals/tutorials/inheritance.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Not all members of a base class are inherited by derived classes. The following

- [Instance constructors](../../programming-guide/classes-and-structs/constructors.md), which you call to create a new instance of the class. Each class must define its own constructors.

- [Finalizers](../../programming-guide/classes-and-structs/destructors.md), which are called by the runtime's garbage collector to destroy instances of a class.
- [Finalizers](../../programming-guide/classes-and-structs/finalizers.md), which are called by the runtime's garbage collector to destroy instances of a class.

While all other members of a base class are inherited by derived classes, whether they are visible or not depends on their accessibility. A member's accessibility affects its visibility for derived classes as follows:

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/language-reference/builtin-types/struct.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ When you design a structure type, you have the same capabilities as with a [clas

- A structure type can't inherit from other class or structure type and it can't be the base of a class. However, a structure type can implement [interfaces](../keywords/interface.md).

- You can't declare a [finalizer](../../programming-guide/classes-and-structs/destructors.md) within a structure type.
- You can't declare a [finalizer](../../programming-guide/classes-and-structs/finalizers.md) within a structure type.

## Parameterless constructors and field initializers

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/language-reference/keywords/class.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ A class can contain declarations of the following members:

- [Fields](../../programming-guide/classes-and-structs/fields.md)

- [Finalizers](../../programming-guide/classes-and-structs/destructors.md)
- [Finalizers](../../programming-guide/classes-and-structs/finalizers.md)

- [Methods](../../programming-guide/classes-and-structs/methods.md)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ The `~` operator produces a bitwise complement of its operand by reversing each

[!code-csharp-interactive[bitwise NOT](snippets/shared/BitwiseAndShiftOperators.cs#BitwiseComplement)]

You can also use the `~` symbol to declare finalizers. For more information, see [Finalizers](../../programming-guide/classes-and-structs/destructors.md).
You can also use the `~` symbol to declare finalizers. For more information, see [Finalizers](../../programming-guide/classes-and-structs/finalizers.md).

## Left-shift operator \<\<

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/misc/cs0245.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ms.assetid: 3f2beb2f-a510-4568-9d11-bb1f65066acd

Destructors and object.Finalize cannot be called directly. Consider calling IDisposable.Dispose if available.

For more information, see [Programming Essentials for Garbage Collection](../../standard/garbage-collection/index.md) and [Finalizers](../programming-guide/classes-and-structs/destructors.md).
For more information, see [Programming Essentials for Garbage Collection](../../standard/garbage-collection/index.md) and [Finalizers](../programming-guide/classes-and-structs/finalizers.md).

The following sample generates CS0245:

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/misc/cs0250.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Do not directly call your base class Finalize method. It is called automatically

A program cannot attempt to force cleanup of base class resources.

See [Finalizers](../programming-guide/classes-and-structs/destructors.md) for more information.
See [Finalizers](../programming-guide/classes-and-structs/finalizers.md) for more information.

The following sample generates CS0250

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ For more information and examples, see [Static Constructors](./static-constructo

- [C# Programming Guide](../index.md)
- [Classes, structs, and records](/dotnet/csharp/fundamentals/object-oriented)
- [Finalizers](./destructors.md)
- [Finalizers](./finalizers.md)
- [static](../../language-reference/keywords/static.md)
- [Why Do Initializers Run In The Opposite Order As Constructors? Part One](/archive/blogs/ericlippert/why-do-initializers-run-in-the-opposite-order-as-constructors-part-one)
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ Finalizers (historically referred to as **destructors**) are used to perform any

For example, the following is a declaration of a finalizer for the `Car` class.

:::code language="csharp" source="snippets/destructors/Program.cs" ID="Snippet2":::
:::code language="csharp" source="snippets/finalizers/Program.cs" ID="Snippet2":::

A finalizer can also be implemented as an expression body definition, as the following example shows.

:::code language="csharp" source="snippets/destructors/expr-bodied-destructor.cs" ID="Snippet1":::
:::code language="csharp" source="snippets/finalizers/expr-bodied-finalizer.cs" ID="Snippet1":::

The finalizer implicitly calls <xref:System.Object.Finalize%2A> on the base class of the object. Therefore, a call to a finalizer is implicitly translated to the following code:

Expand Down Expand Up @@ -77,7 +77,7 @@ The following example creates three classes that make a chain of inheritance. Th
* .NET Framework: The output shows that the finalizers for the three classes are called automatically when the application terminates, in order from the most-derived to the least-derived.
* .NET 5 (including .NET Core) or a later version: There's no output, because this implementation of .NET doesn't call finalizers when the application terminates.

:::code language="csharp" source="snippets/destructors/Program.cs" ID="Snippet1":::
:::code language="csharp" source="snippets/finalizers/Program.cs" ID="Snippet1":::

## C# language specification

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ C# [records](../../fundamentals/types/records.md) provide a copy constructor for
- [C# Programming Guide](../index.md)
- [Classes, structs, and records](/dotnet/csharp/fundamentals/object-oriented)
- [Constructors](./constructors.md)
- [Finalizers](./destructors.md)
- [Finalizers](./finalizers.md)
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,5 @@ class Circle : Shape
- [C# Programming Guide](../index.md)
- [Classes, structs, and records](/dotnet/csharp/fundamentals/object-oriented)
- [Constructors](./constructors.md)
- [Finalizers](./destructors.md)
- [Finalizers](./finalizers.md)
- [static](../../language-reference/keywords/static.md)
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Classes and structs have members that represent their data and behavior. A class
|[Operators](../../language-reference/operators/index.md)|Overloaded operators are considered type members. When you overload an operator, you define it as a public static method in a type. For more information, see [Operator overloading](../../language-reference/operators/operator-overloading.md).|
|[Indexers](../indexers/index.md)|Indexers enable an object to be indexed in a manner similar to arrays.|
|[Constructors](./constructors.md)|Constructors are methods that are called when the object is first created. They are often used to initialize the data of an object.|
|[Finalizers](./destructors.md)|Finalizers are used very rarely in C#. They are methods that are called by the runtime execution engine when the object is about to be removed from memory. They are generally used to make sure that any resources which must be released are handled appropriately.|
|[Finalizers](./finalizers.md)|Finalizers are used very rarely in C#. They are methods that are called by the runtime execution engine when the object is about to be removed from memory. They are generally used to make sure that any resources which must be released are handled appropriately.|
|[Nested Types](./nested-types.md)|Nested types are types declared within another type. Nested types are often used to describe objects that are used only by the types that contain them.|

## See also
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ For more information, see [Private constructors](~/_csharplang/spec/classes.md#p
- [C# Programming Guide](../index.md)
- [Classes, structs, and records](/dotnet/csharp/fundamentals/object-oriented)
- [Constructors](./constructors.md)
- [Finalizers](./destructors.md)
- [Finalizers](./finalizers.md)
- [private](../../language-reference/keywords/private.md)
- [public](../../language-reference/keywords/public.md)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public class Destroyer
{
public override string ToString() => GetType().Name;

~Destroyer() => Console.WriteLine($"The {ToString()} destructor is executing.");
~Destroyer() => Console.WriteLine($"The {ToString()} finalizer is executing.");
}
// </Snippet1>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ For more information, see the [Static constructors](~/_csharplang/spec/classes.m
- [Classes, structs, and records](/dotnet/csharp/fundamentals/object-oriented)
- [Constructors](./constructors.md)
- [Static Classes and Static Class Members](./static-classes-and-static-class-members.md)
- [Finalizers](./destructors.md)
- [Finalizers](./finalizers.md)
- [Constructor Design Guidelines](../../../standard/design-guidelines/constructor.md#type-constructor-guidelines)
- [Security Warning - CA2121: Static constructors should be private](/visualstudio/code-quality/ca2121-static-constructors-should-be-private)
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@ For more information, see [Instance constructors](~/_csharplang/spec/classes.md#
- [C# Programming Guide](../index.md)
- [Classes, structs, and records](/dotnet/csharp/fundamentals/object-oriented)
- [Constructors](./constructors.md)
- [Finalizers](./destructors.md)
- [Finalizers](./finalizers.md)
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ An expression body definition for a finalizer typically contains cleanup stateme

The following example defines a finalizer that uses an expression body definition to indicate that the finalizer has been called.

[!code-csharp[expression-bodied-finalizer](../classes-and-structs/snippets/destructors/expr-bodied-destructor.cs#1)]
[!code-csharp[expression-bodied-finalizer](../classes-and-structs/snippets/finalizers/expr-bodied-finalizer.cs#1)]

For more information, see [Finalizers (C# Programming Guide)](../classes-and-structs/destructors.md).
For more information, see [Finalizers (C# Programming Guide)](../classes-and-structs/finalizers.md).

## Indexers

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ items:
- name: "How to write a copy constructor"
href: programming-guide/classes-and-structs/how-to-write-a-copy-constructor.md
- name: Finalizers
href: programming-guide/classes-and-structs/destructors.md
href: programming-guide/classes-and-structs/finalizers.md
- name: Object and Collection Initializers
href: programming-guide/classes-and-structs/object-and-collection-initializers.md
- name: "How to initialize objects by using an object initializer"
Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/tour-of-csharp/program-building-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ The first `Console.WriteLine` outputs `True` because the two lists contain the s

### Finalizers

A *finalizer* is a member that implements the actions required to finalize an instance of a class. Typically, a finalizer is needed to release unmanaged resources. Finalizers can't have parameters, they can't have accessibility modifiers, and they can't be invoked explicitly. The finalizer for an instance is invoked automatically during garbage collection. For more information, see the article on [finalizers](../programming-guide/classes-and-structs/destructors.md).
A *finalizer* is a member that implements the actions required to finalize an instance of a class. Typically, a finalizer is needed to release unmanaged resources. Finalizers can't have parameters, they can't have accessibility modifiers, and they can't be invoked explicitly. The finalizer for an instance is invoked automatically during garbage collection. For more information, see the article on [finalizers](../programming-guide/classes-and-structs/finalizers.md).

The garbage collector is allowed wide latitude in deciding when to collect objects and run finalizers. Specifically, the timing of finalizer invocations isn't deterministic, and finalizers may be executed on any thread. For these and other reasons, classes should implement finalizers only when no other solutions are feasible.

Expand Down
6 changes: 3 additions & 3 deletions docs/framework/performance/performance-tips.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: ".NET Performance Tips"
description: Explore performance tips to improve the execution speed of a program in .NET. See tips for boxing and unboxing, strings, and destructors.
description: Explore performance tips to improve the execution speed of a program in .NET. See tips for boxing and unboxing, strings, and finalizers.
ms.date: "03/30/2017"
helpviewer_keywords:
- "C# language, performance"
Expand All @@ -23,9 +23,9 @@ The term *performance* generally refers to the execution speed of a program. You

When you concatenate a large number of string variables, for example in a tight loop, use <xref:System.Text.StringBuilder?displayProperty=nameWithType> instead of the C# [+ operator](../../csharp/language-reference/operators/addition-operator.md) or the Visual Basic [Concatenation Operators](../../visual-basic/language-reference/operators/concatenation-operators.md). For more information, see [How to concatenate multiple strings](../../csharp/how-to/concatenate-multiple-strings.md) and [Concatenation Operators in Visual Basic](../../visual-basic/programming-guide/language-features/operators-and-expressions/concatenation-operators.md).

## Destructors
## Finalizers

Empty destructors should not be used. When a class contains a destructor, an entry is created in the Finalize queue. When the destructor is called, the garbage collector is invoked to process the queue. If the destructor is empty, this simply results in a loss of performance. For more information, see [Destructors](../../csharp/programming-guide/classes-and-structs/destructors.md) and [Object Lifetime: How Objects Are Created and Destroyed](../../visual-basic/programming-guide/language-features/objects-and-classes/object-lifetime-how-objects-are-created-and-destroyed.md).
Empty finalizers should not be used. When a class contains a finalizer, an entry is created in the Finalize queue. When the finalizer is called, the garbage collector is invoked to process the queue. If the finalizer is empty, this simply results in a loss of performance. For more information, see [Finalizers](../../csharp/programming-guide/classes-and-structs/finalizers.md) and [Object Lifetime: How Objects Are Created and Destroyed](../../visual-basic/programming-guide/language-features/objects-and-classes/object-lifetime-how-objects-are-created-and-destroyed.md).

## Other Resources

Expand Down
2 changes: 1 addition & 1 deletion docs/standard/garbage-collection/implementing-dispose.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Here's the general pattern for implementing the dispose pattern for a base class
:::code language="vb" source="../../../samples/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/base2.vb":::

> [!TIP]
> In C#, you create a finalizer by providing a [destructor](../../csharp/programming-guide/classes-and-structs/destructors.md), not by overriding <xref:System.Object.Finalize%2A?displayProperty=nameWithType>. In Visual Basic, you create a finalizer with `Protected Overrides Sub Finalize()`.
> In C#, you implement a finalization by providing a [finalizer](../../csharp/programming-guide/classes-and-structs/finalizers.md), not by overriding <xref:System.Object.Finalize%2A?displayProperty=nameWithType>. In Visual Basic, you create a finalizer with `Protected Overrides Sub Finalize()`.

## Implement the dispose pattern for a derived class

Expand Down
2 changes: 1 addition & 1 deletion docs/standard/garbage-collection/unmanaged.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ If your types use unmanaged resources, you should do the following:

—**or**—

- Define a [finalizer](../../csharp/programming-guide/classes-and-structs/destructors.md). Finalization enables the non-deterministic release of unmanaged resources when the consumer of a type fails to call <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> to dispose of them deterministically.
- Define a [finalizer](../../csharp/programming-guide/classes-and-structs/finalizers.md). Finalization enables the non-deterministic release of unmanaged resources when the consumer of a type fails to call <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> to dispose of them deterministically.

> [!WARNING]
> However, because object finalization can be a complex and an error-prone operation, we recommend that you use a safe handle instead of providing your own finalizer.
Expand Down