Writing your own destructor (aka finalizer) is erroneous in 99.99% of all cases. They are necessary to ensure that your class releases an operating system resource that is not automatically managed by the .NET platform and is not correctly released by the user of your class.
This starts with the need to first allocate the operating system resource into its own code. It always requires a kind of P / Invoke. This is very rarely necessary, it is the work of .NET programmers working at Microsoft to take care of this.
They did this in the case of StreamWriter. Through several layers, this is a wrapper around the file descriptor created using CreateFile (). The class that created the handle is also the one responsible for writing the finalizer. Microsoft code, not yours.
Such a class always implements IDisposable, giving the user of the class the opportunity to release the resource when it is executed with it, instead of waiting for the finalizer to complete. StreamWriter implements IDisposable.
Of course, your StreamWriter object is a private implementation of your class. You do not know when the user has executed his Logger class, you cannot automatically call StreamWriter.Dispose (). You need help.
Get this help by implementing IDisposable yourself. The user of your class can now call Dispose or use the using statement, as with any of the framework classes:
class Logger : IDisposable { private StreamWriter sw; public void Dispose() { sw.Dispose();
Well, that is what you should do in 99.9% of all cases. But not here. At the risk of falsifying you: if you implement IDisposable, there should be a reasonable opportunity for the user of your class to call the Dispose () method. This is usually not a big problem, except for a class like Logger. It is likely that your user wants to register something until the last moment. So that she can register an unhandled exception from AppDomain.UnhandledException, for example.
When to call Dispose () in this case? You can do this when your program terminates. But, besides this, it makes no sense to allocate resources earlier if this happens when the program exits.
The registrar has a special requirement for proper closure in all cases. This requires that you set the StreamWriter.AutoFlush property to true so that the log output is reset as soon as it is recorded. Given the complexity of correctly calling the Dispose () function, it is now better if you do not implement IDisposable and do not allow the Microsoft finalizer to close the file descriptor.
Fwiw, there is another class within the framework that has the same problem. The Thread class uses four operating system descriptors, but does not implement IDisposable. Calling Thread.Dispose () is really inconvenient, so Microsoft did not execute it. This causes problems in very unusual cases, you need to write a program that creates many threads, but never uses a new operator to create class objects. That was done.
And last but not least, writing a logger is quite difficult, as explained above. Log4net is a popular solution. NLog is the best mousetrap, a library that feels and operates dotnetty, instead of feeling like a Java port.