It's funny this is mentioned. Misconceptions about .NET are unfortunate but unsurprising.
There is no such thing as IL finalizers. There are object finalizers which are highly discouraged to be used on their own.
Their most frequent application is a safety measure for objects implementing IDisposable where not calling Dispose could lead to memory leak or other form of resource starvation that must be prevented.
For example, a file handle is IDisposable, so it is naturally disposed through using statement but should a user make a mistake in a scenario where that handle has non-trivial lifecycle, once the object is no longer referenced, its finalizer will be called upon one of the Gen2 GCs by a finalizer thread, preventing the file handle leakage even if its freeing is now non-deterministic:
// Disposed upon exiting the scope
using var okay = File.OpenHandle("file1");
// IDEs will complain if you do this, but if you insist,
// the implementation will prevent you from shooting your
// foot off even if it'll hurt until next Gen2 GC
var leaked = File.OpenHandle("file2");
there is dedicated mechanism to achieve RAII-likeness in .NET: try-finally construct