How to find out an unmanaged class in C #
This immediately disconnects you on the wrong track, all classes are managed in C #. The language does not support the use of unmanaged classes at all. None of the .NET languages do except one: C ++ / CLI. This is a rather atypical language specifically designed to help a programmer use his own C ++ class. The use of this language is specialized and is not related to this issue.
It is important whether the managed class is a wrapper for an unmanaged resource. A wrapper is a class that has a purely managed interface, but which internally uses an unmanaged resource, usually through pinvoke with the [DllImport] attribute. A resource is almost always represented by IntPtr
. Unmanaged handle or pointer.
Such a shell needs a finalizer to ensure that an unmanaged resource is always released. If this does not happen, then you have a leak, an error that (eventually) crashes out of the program when the operating system gets frustrated with the program using too many resources.
And since it has a finalizer, it also implements IDisposable. Allow a program to release an unmanaged resource earlier before the GC approaches the finalizer call. Using the Dispose () method or using statement is optional; the finalizer is good enough to ensure that the job is completed.
But sometimes the finalizer is not good enough, because the program does not create garbage fast enough, and then it is very important that you help. You really can't know if you need help, so most .NET programmers always do this. And a subset never does and never noticed a problem in years of programming. We eventually hear from them at SO :)
Your StreamReader example is good to go to the next step. StreamReader does not actually wrap an unmanaged resource. All his code is written in C #, and he has no pinvoke, in his body there is no uncontrollable bone. And therefore does not have a finalizer. But still has a Dispose () method.
StreamReader got "infected". It is also a wrapper class, but for a stream, not for IntPtr. A purely managed abstract type of .NET, the wrapper itself. What implements IDisposable, now StreamReader must also implement it. Therefore, when you call the StreamReader Dispose () method, the Stream.Dispose () method can execute.
This is an overlay for work; there is a hierarchy of classes. StreamReader wraps Stream, which wraps FileStream, which wraps SafeFileHandle, which actually wraps IntPtr. Only SafeFileHandle has a finalizer.
Understanding layers is where everyone refuses, which requires a fairly deep understanding of how these .NET classes are structured. You can get there, but it takes many years. There are three main shortcuts:
Understand how the operating system works. Gives you the idea that the file is a resource of the operating system, put your prey that when using the file you need to destroy it or close it.
Use the MSDN library article for the class you are using. When you see that it has a Dispose () method, there is almost always a good reason to use it. Sometimes not, but you will never be mistaken when you use it anyway.
Fix problems, make every mistake every programmer must make, use SO or a memory profiler to find out what you did wrong. Nothing wrong with learning how to do it right.