Skip to content

CS0465 description doesn't match behavior #55617

Description

@GeeLaw

Type of issue

Outdated article

Description

CS0465 documentation says:

This warning occurs when you create a class with a method whose signature is public virtual void Finalize.

If such a class is used as a base class and if the deriving class defines a finalizer, the finalizer will override the base class Finalize method, not Finalize.

However, currently (used from VS 18.9.1 on Windows 11 x64, targeting .NET 10 AnyCPU), the actual behavior is different.

  • The warning is (IMO correctly) emitted for all accessibility modifiers (except private, which C# anyway doesn't allow for virtual methods).
  • Suppose B introduces protected virtual void Finalize() { } (new slot).
  • Suppose D : B defines a finalizer ~D() { }.

The effect is as follows:

  • D's finalizer overrides both B.Finalize and object.Finalize. The C# compiler emits explicit .override object::Finalize() in D's synthesized Finalize, so it does override object.Finalize. The method is also non-newslot and virtual, so it overrides B.Finalize due to matching name and signature.
  • D's finalizer will call instance B.Finalize, which is, of course, not the finalizer (I take "finalizer" to mean the override of object.Finalize).

More interestingly, if B.Finalize is...

  • public or internal or protected internal, then type D fails to load (override cannot reduce access);
  • private protected, then D.Finalize overrides B.Finalize and object.Finalize, and in D.Finalize, it calls object.Finalize not B.Finalize (this happens even if B.Finalize is accessible to D);
  • non-virtual but protected or protected internal, then D.Finalize will call B.Finalize (and not object.Finalize), but of course only overrides object.Finalize.

Maybe the documentation was accurate for some versions of C# compiler. I suspect the situation is simply unsupported as defining a method called Finalize (except via the finalizer syntax) is anyway a very bad idea. If both are true, I suggest avoiding describing what happens when one defines such a method, and simply say "doing so interferes with finalization logic".

Page URL

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0465?f1url=%3FappId%3Droslyn%26k%3Dk(CS0465)

Content source URL

https://github.com/dotnet/docs/blob/main/docs/csharp/language-reference/compiler-messages/cs0465.md

Document Version Independent Id

53f17a1d-75c8-7fe6-1b0c-7893ae6fc0c4

Platform Id

ac53118f-3da2-cf27-577d-9745af24231b

Article author

@BillWagner

Metadata

  • ID: 93138196-598c-7726-1b74-4cb6e4b302a3
  • PlatformId: ac53118f-3da2-cf27-577d-9745af24231b
  • Service: dotnet-csharp
  • Sub-service: errors-warnings

Related Issues


Associated WorkItem - 627639

Metadata

Metadata

Assignees

Type

No type

Projects

Status
👀 In review

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions