Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I force subclasses to override a method without making it abstract?

I have a class with some abstract methods, but I want to be able to edit a subclass of that class in the designer. However, the designer can't edit the subclass unless it can create an instance of the parent class. So my plan is to replace the abstract methods with stubs and mark them as virtual - but then if I make another subclass, I won't get a compile-time error if I forget to implement them.

Is there a way to mark the methods so that they have to be implemented by subclasses, without marking them as abstract?

like image 404
Simon Avatar asked Oct 27 '08 09:10

Simon


2 Answers

Well you could do some really messy code involving #if - i.e. in DEBUG it is virtual (for the designer), but in RELEASE it is abstract. A real pain to maintain, though.

But other than that: basically, no. If you want designer support it can't be abstract, so you are left with "virtual" (presumably with the base method throwing a NotImplementedException).

Of course, your unit tests will check that the methods have been implemented, yes? ;-p

Actually, it would probably be quite easy to test via generics - i.e. have a generic test method of the form:

[Test]
public void TestFoo() {
  ActualTest<Foo>();
}
[Test]
public void TestBar() {
  ActualTest<Bar>();
}

static void ActualTest<T>() where T : SomeBaseClass, new() {
  T obj = new T();
  Assert.blah something involving obj
}
like image 86
Marc Gravell Avatar answered Oct 21 '22 02:10

Marc Gravell


You could use the reference to implementation idiom in your class.

public class DesignerHappy
{
    private ADesignerHappyImp imp_;

    public int MyMethod()
    {
        return imp_.MyMethod()    
    }

    public int MyProperty
    {
        get { return imp_.MyProperty; }
        set { imp_.MyProperty = value; }
    }
}

public abstract class ADesignerHappyImp
{
    public abstract int MyMethod();
    public int MyProperty {get; set;}
}

DesignerHappy just exposes the interface you want but forwards all the calls to the implementation object. You extend the behavior by sub-classing ADesignerHappyImp, which forces you to implement all the abstract members.

You can provide a default implementation of ADesignerHappyImp, which is used to initialize DesignerHappy by default and expose a property that allows you to change the implementation.

like image 22
Curro Avatar answered Oct 21 '22 04:10

Curro