Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VisualStudio 2010 Designer throws on implemented virtual method

I want to have an abstract UserControl, BaseControl, that implements an interface IBaseControl. However, setting the class to abstract breaks VisualStudio designer (This is a known issue with Visual Studio (e.g., see this StackOverflow posting for more info), and as far as I know, there's no change expected in the near future

So, to work around this, I make BaseControl not abstract, and its implementation of IBaseControl methods virtual. However, since these methods make no sense for a BaseControl (e.g., not all components have been added yet), I make them throw:

public class BaseControl : UserControl, IBaseControl
{
    /// <summary>
    /// This IBaseControl method is not abstract because 
    /// that breaks the Designer
    /// </summary>
    public virtual void LoadSettings()
    {
        throw new NotImplementedException("Implement in derived class.");
    }

    private void BaseControl_Load(object sender, EventArgs e)
    {
        // intention: derived methods automagically load their settings
        this.LoadSettings();
    }
}

In the derived control, I have the corresponding override:

public partial class DerivedControl : BaseControl
{
    public override void LoadSettings()
    {
        // load settings
    }
}

Despite this, when I try to open the control in the designer, I get an error indicating that the BaseControl.LoadSettings has thrown an exception.

Now, remember LoadSettings is called in the base class, so when the Designer loads the DerivedControl, it in turn calls the load method for the BaseControl, which throws.

Have you encountered a similar problem? How have you dealt with this? I'd like to have an elegant solution, if possible.

like image 934
Gustavo Mori Avatar asked Jun 09 '11 20:06

Gustavo Mori


People also ask

Is it mandatory to override virtual method in C#?

When the method is declared as virtual in a base class, and the same definition exists in a derived class, there is no need for override, but a different definition will only work if the method is overridden in the derived class. Two important rules: By default, methods are non-virtual, and they cannot be overridden.

Are methods virtual by default?

By default, methods are non-virtual. You cannot override a non-virtual method. Virtual properties behave like virtual methods, except for the differences in declaration and invocation syntax. It is an error to use the virtual modifier on a static property.

Can virtual method be empty?

The solution with empty virtual methods gives no information on what is supported by a specific document instance. Furthermore, it forces you to add all possible methods in the base class. This forces all clients to be updated as whel, when you decide that the base class needs additional methods.

Can abstract methods be virtual?

Yes, abstract methods are virtual by definition; they must be overridable in order to actually be overridden by subclasses: When an instance method declaration includes an abstract modifier, that method is said to be an abstract method.


1 Answers

The reason that the exception is thrown is because, oddly enough, the designer doesn't compile or instantiate the class your are designing at all! It only compiles and instantiates the base class of the control you are designing.

Why this is the case becomes obvious when you realize that adding new subcontrols to the element would require further recompilation. Also, every event handler that you add modifies the class and again would require recompilation. Since event handlers will never be called in the designer anyway, this is all completely unnecessary. You design with a class that resembles your class but isn't your class; it's a work in progress.

Since only the base class is instantiated, the base class cannot be abstract and it needs to be functional as is. If you throw exceptions, then the designer will see them. The only practical solution is to either:

  • Not throw exceptions from the base class, or
  • Conditionally not throw exceptions based on whether it is design-time or not.

Either will work; use whichever you prefer or works best for your design. This is just the way the designer works and as you mention it is not likely to change.

like image 54
Rick Sladkey Avatar answered Sep 17 '22 18:09

Rick Sladkey