views:

161

answers:

3

I have an abstract class which requires a delegate to function. I pass the delegate into the constructor. Now that I have a non default constructor I need to call the abstract class's constructors from the concrete class which means that I need to use MyBase.New(...). I have included a quick example below.

Public MustInherit Class BaseClass
    Public Delegate Sub WorkMethod()
    Private _Work As WorkMethod

    Public Sub New(ByVal Work As WorkMethod)
        Me._Work = WorkMethod
    End Sub
End Class

Public Class ConcreteClass
    Public Sub New()
        MyBase.New(AddressOf DoSomethingHere)
    End Sub

    Public Sub DoSomethingHere()
        'Do some work here
    End Sub
End Class

I have tried to do this but I keep getting the following error: "Implicit reference to object under construction is not valid when calling another constructor".

Can I not do what I am trying to do above? I initially had the delegate setup in its own setter method. But then I am creating a deceptive API because it does require a point to a method to work properly.

+2  A: 

Rather than take a delegate, is there any reason not to specify an abstract method in the base class, and implement it in the concrete class? That would be the normal way of achieving this sort of thing.

If you want a delegate for other reasons, you can always create it from the abstract method in the base class.

(There are other times when it's a bit of a pain that you can't access Me/this in constructor arguments; I feel your pain here, but I think using an abstract method is probably a better fit for the situation you've described.)

Jon Skeet
I have been at this too long. That is how I should be doing it. I don't know why I didn't even think of it. Sorry to waste everyone's time. What a beginner mistake to make.
uriDium
+2  A: 

You can't pass something belonging to ConcreteClass because the object is still under construction when calling the constructor of the base class. It thus can't be used at that time.

Adding an abstract method to the base sounds more reasonable.

+1  A: 

During the base class constructor, only the base class parts of the object are complete -- It's really just a BaseClass object until the ConcreteClass constructor completes. Hence you would not be able to call DoSomethingHere in the base ctor. You don't do that, but the compiler doesn't know that, and has to assume that you will.

If you make it into a static function (with ConcreteClass passed in as a parameter), it should work.

James Curran