For those who work with .NET inheritance, it is quite common to write
abstract classes in order to store portions of code which will be shared by sibling subclasses and therefore enforce the code reuse. Obviously, sibling subclasses may include
System.Windows.Forms.Form classes; for example, an application using an MVC pattern may have forms inheriting from an
abstractclass implementing a View. Most commonly, base
abstractclasses for forms can be useful to share common behaviours between forms (a title, a set of buttons or methods and so on).
Problems appear when you try to edit a
Form inherited from an
abstractclass with Visual Studio Designer: an error message fires, stating that "The designer must create an instance but it cannot because the type is declared as
abstract". The same error is fired by SharpDevelop, revealing that this is not just a Visual Studio bug but, probably, a Framework architectural issue.
Delphi's and Borland Builder C++'s designers perfectly handle
abstractbased forms but .NET doesn't. Moreover, Microsoft doesn't plan to solve the inability to cope with abstract forms in upcoming Visual Studio versions.
To solve this problem, a few workarounds can be used: in this article I will introduce the one I consider to be the most comfortable to use, but which is neither the best nor the most elegant one.
The trick consists in inheriting the form from an
abstractclass only in release builds and in writing a suitable concrete version of it which can be used only at design time and in debug builds.
Understanding the reason for this behaviour may not be strictly necessary but it could be nevertheless interesting.
We could believe that, in order to edit a Form, the Designer just needs to directly instantiate it. Far from it, the error message clearly states that the Designer needs to instantiate the base class rather than the derived one but, being the first one
abstract, no instance of it can be created.
As a matter of fact, when the Designer handles with Forms, it first uses Reflection to create an instance of the base class (
System.Windows.Forms.Form), then it parses the
InitalizeComponent method of the derived class and it finally applies all the derived class's properties on the base class's instance, hence allowing the user to modify the derived class. In short, the user always works with a base class modified on-the-fly.
In his excellent article Brian Pepin lists some of the fixes Microsoft took into consideration and explains in details why none of them have been adopted.
Some articles propose to change the OO architecture in order to prevent the problem from appearing.
The widespread solution is to avoid the use of
abstractmethods (which would tag the entire base class as
abstract) and use instead empty virtual methods. Doing that, the class behaves like
abstract, but works in the Designer too. The main problem with this approach is related to the differences between virtual and
Virtual methods allow subclasses to override the base method (eventually, empty) with their own implementation, while
abstract ones, which are implicitly virtual, strictly require the class to provide an implementation using the same signature. Using virtual methods may lead the developer to incidentally forget to provide an implementation: in this case, no alert by the compiler would be fired. A further suggestion could be, then, to always write virtual methods throwing a
NotImplementedException to remind the developer to override the method. It would happen only at run-time and you may agree that a solution enforced by the compiler would be much more comfortable.
It's not generally a good idea to change the architecture in order to just get around a problem: an object-oriented hierarchy is supposed to have been chosen with a strong, clear and correct design architecture in mind and an approach which can preserve the exact hierarchy is generally a better approach.
Brian Pepin (again) suggests the best solution which both preserves the exact OO design and completely solves the problem. Unfortunately, Brian's approach only works with Visual Studio Whidbey (2005) and, even if it's almost perfect and really elegant, it's considerably less immediate than the following solution. Let me stress again that Brian's solution is the real good one. The one described here should be considered just an enhanced version of the virtual methods solution, with the only advantage of being very simple and of working on every Visual Studio version.
The weakness of the virtual methods solution is the lack of compiler's alerts in the case of a missing method implementation. As stated in the introduction, you may provide two classes, one
abstract and the other one concrete, to be used respectively for build and for debug releases. Instead of writing two separate files, it's easier to use an
#if compiler directive which switches between the two class definitions:
public class AbstractForm : Form
public abstract class AbstractForm: Form
public virtual void MyMethod()
throw new NotImplementedException();
public abstract void MyMethod();
You can switch between Debug and Build releases in Visual Studio with a bunch of clicks (few more with SharpDevelop), but you should remember to recompile your project and close and reopen your form in order to inform the Designer about the changes.
With this simple trick, a release build will throw a compiling error for a missing overridden method, while in debug mode every form will be perfectly editable.
Visual Studio is smart enough to correctly deal with curly brackets, ignoring open parenthesis in not enabled portions of code; SharpDevelop is less efficient and throws errors declaring not closed brackets.
Since I'm a big SharpDevelop's fan, I found it very frustrating. The only workaround I managed to obtain for SharpDevelop is not that elegant, but it's perfectly working. The trick is avoiding curly brackets to appear inside a
#if statement, like in the next sample code:
class AbstractForm : Form
throw new NotImplementedException();
abstract void MyMethod();
In the sample code, the form
DerivedForm inherits from
AbstractForm, which is concrete in debug builds and
abstractin release ones.
AbstractForm defines respectively
MyMethod as a virtual method (throwing an
NotImplementedException) or an
You can comment the
#define directive in the first line of the sample code in order to disable the implementation of
public override void MyMethod()
You can verify that in debug mode, both
AbstractCode can be successfully modified in Visual Studio Form Designer. As explained, if
MyMethod() is not implemented in the derived class, a release build compilation fails.
DerivedClass there's a little piece of code doing some reflection in order to find out which version of
MyMethod() will be called:
private void CallMyMethod_Click(object sender, EventArgs e)
Type type = this.GetType();
MethodInfo methods = type.GetMethods();
foreach (MethodInfo info in methods)
if (info.Name == "MyMethod")
if (info.DeclaringType.FullName ==
- 2008.09.01 First version of the article
- 2008.15.01 Fixed the wrong Whidbey version