#
On reflection: making use of internal system classes
August 7, 2006 | 7:16 PM | | Post comment
It is commonly known that reflection is a powerhouse. And as every raw power it has to be treated with extra care (e.g. reflection easily breaks the encapsulation.) A point that is often overlooked is that one can access private and internal methods (classes, etc.) via reflection mechanism. This technique, which essentially relies on the late binding, depends on the fact that one knows the name of the entity to access. Unless the developer has a full control over the private member it is very dangerous to assume that its name is going to stay. For example, obfuscation would break the code that blindly relies on the naming of the private members. However, there are situations when such a technique can be extremely useful.
One thing that I absolutely love about the .NET Framework libraries is that these are not obfuscated. The one thing I hate is that some of very useful classes are made internal. Reflection to the rescue! Names of classes in system libraries are set in stone (at least between major releases) and, hence, make a perfect target for reflecting upon.
.NET libraries themselves utilize reflection a lot. Equipped with this knowledge you can do some magic tricks. For example, EditorAttribute accepts a string with the name of the editor class. Naturally reflection is going to be used behind the scene to instantiate an editor. What does it give us? Well, it suggests that you can use all those fancy internal editors, like ImageIndexEditor. All you have to do is to specify the name of the class (optionally the full name including the assembly) and let the reflection do the rest.
[Editor("System.Windows.Forms.Design.ImageIndexEditor",
typeof(UITypeEditor))]
public int ImageIndex { ... }
#
Why calling Dispose() in the constructor is bad!
July 25, 2006 | 12:02 AM | | Post comment
Recently I have been reviewing some of the production C# code where I noticed that the programmer was calling Dispose() method in the class constructor. He was doing that for a reason, because that particular class was wrapping on several unmanaged resources. Resources were initialized right in the constructor one after another in a try/catch block. The catch invoked Dispose() to make sure that everything already initialized would go away should an exception be thrown down the road. Even though the approach seems viable, this practice is very dangerous as it usually leads to very unpleasant side effects.
Let us see what can happen is such situation. Consider a base class that invokes Dispose() in its constructor (naturally, it implements IDisposable interface as well):
public class BaseClassWithDispose : IDisposable
{
protected AdvancedBaseClass ()
{
// do not do this!
try { ... } catch { Dispose () ; throw ; }
}
public void Dispose ()
{
Dispose (true) ;
GC.SuppressFinalize (this) ;
}
protected virtual void Dispose (bool disposing)
{
// usual dispose pattern implementation
}
}
Except for the Dispose() invocation this class looks ok. Now, let’s extend this class by a class that also wraps an unmanaged resource.
public class UnmanagedResourceWrapper : BaseClassWithDispose
{
private Resource m_unmanagedResource ;
private bool m_disposed = false ;
public UnmanagedResourceWrapper ()
{
m_unmanagedResource = ... ;
}
protected override void Dispose (bool disposing)
{
if (!m_disposed)
{
if (m_unmanagedResource != null)
m_unmanagedResource.Release () ;
}
m_disposed = true ;
base.Dispose (disposing) ;
}
}
Note, that this class allocates the resource in the constructor (we omit try/catch sections for the sake of presentation).
Nothing special so far. But, wait… let’s take a closer look at what happens when Dispose() gets called in the base class. Because of the fact that Dispose(bool) method is virtual the UnmanagedResourceWrapper.Dispose(bool) will be called prior to its constructor invocation. That means that the instance is going to be disposed before it even gets a chance to proper construct itself. Should this be a purely managed instance you wouldn’t even notice, but we are wrapping on the unmanaged resource here. The constructor would eventually be called (disposing makes no difference here) and the unmanaged resource gets allocated. However, as you may have guessed already, it would never be released (m_disposed is already set to true at this point). VoilĂ , we get a resource leak.
Morale of the story?
- do not call Dispose() in constructors,
- do not initialize (unmanaged) resources in constructors, and if you really need to, make sure to release them manually and implement a proper Dispose pattern to handle this situation.