I'm Using Visual Studio 2017 to write C# apps. I strive to dispose of all objects I instantiate by utilizing the "using" statement. Visual Studio warns me if I instantiate an object NOT based on a type that is implicitly convertible to 'System.IDisposable'. This example results in VS displaying the warning (C#):
using (uri = new System.Uri(stringVarWithPath))
{
}
Are all types that don't implement a Dispose method unmanaged? I ask because "Implementing a Dispose Method" (https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose) seems to imply its applicable only to unmanaged resources.
It's the other way around.
First, all types you work with in .NET are managed. But some managed types encapsulate unmanaged resources, such as Windows handles.
The types that encapsulate unmanaged resources, usually implement
IDisposable. TheIDisposableinterface lets you explicitly release unmanaged resources held by these objects, by either callingDispose(), or putting them inusing. In the latter case,Dispose()is called automatically when exiting the scope of theusing.In any way, even if
Dispose()is not called on an object that implements it, well designed classes should release their unmanaged resources inFinalize()(which is basically destructor). ButFinalize()is invoked by the GC, and we don't know how often the GC is invoked, which meakes the process of releasing resources non-deterministic. WithoutIDisposable, we'd hold expensive unmanaged resources for extended periods of time, much more than might be necessary.When a type doesn't implement
IDisposable, it is an indication that it holds no unmanaged resources, and it has no reason to be explicitly disposed (provided the type is well-designed, of course).Note that some types that implement
IDisposabledon't actually hold any unmanaged resources. For example, a class that measures time of execution can implementIDisposable, so that it saves a timestamp in constructor, then inDisposeit takes current timestamp and calculates elapsed time and reports it to some logging mechanism. When you put such a class insideusing, you get a convenient way of measuring execution time of your code blocks.