views:

57

answers:

3

I have a base class with several derived classes. I want all of my derived classes to have the same Public Shared (static) method with their own implementation. How do I do this? Is it even possible?

A: 

No. You could use a singleton, but there may be a better design.

Matthew Flaschen
A: 

By definition, a static method cannot be declared as virtual. To achieve this without static methods you would do something like the following:

public abstract class BaseFoo
{
    protected virtual void Bar()
    {
    }
}

public class Foo : BaseFoo
{
    protected override void Bar()
    {
        base.Bar();
    }
}

If you wanted to achieve something similar to having it as static you could use the singleton pattern so that you share a single instance of the object.

Edit:

I realized your original question talked about VB syntax, so here's the same thing in VB:

Public MustInherit Class BaseFoo

    Protected Overridable Sub Bar()
    End Sub

End Class

Public Class Foo
    Inherits BaseFoo

    Protected Overrides Sub Bar()
        MyBase.Bar()
    End Sub

End Class
Greg Shackles
is there any reason for this? it seems stupid that you can't declare a static method sig that can be used across all classes.
Jason
RE: your edit - yep, thanks... i was able to convert it in my head, but yeah i'm working in vb for this project :)
Jason
What are you trying to achieve by doing this? A virtual method relies on an instantiated object, whereas a static method exists without needing the object to be created. That's why static methods can only reference other static variables/methods.If it's simply the method signature you're trying to share, the example I gave before shows that the signature would get shared. Without knowing your exact scenario here, I'd say you'd probably benefit from either the singleton pattern or dependency injection.
Greg Shackles
If I have `BaseForm` and then `ChildFormTypeA` `ChildFormTypeB`, I want to be able to call `ChildFormTypeA.GetForms()` and `ChildFormTypeB.GetForms()` and have them do the same exact thing conceptually, except the details are slightly different because each method needs to know something slightly unique so it can get the appropriate forms. I suppose I could have a giant `Select` statement, but that sucks. There HAS to be a way...
Jason
What I'm saying is that they do the same thing, but their implementation details require something slightly different. It would be perfect if I could declare `BaseForm.GetForms()` as `MustOverride` and just include the implementation details there, but I can't.
Jason
+2  A: 

I know this seems like a useful feature "at design time" but imagine how this could be used:

If GetForms is Shared (static in C#) you don't have an object with a type to distinguish which method to use, i.e. you can't say BaseForm.GetForms() in some way that it can be determined which of ChildFormTypeA.GetForms() and ChildFormTypeB.GetForms() is actually called.

The best you can do is document this is the intention if you just want explicit calls to ChildFormTypeA.GetForms() and ChildFormTypeB.GetForms(), or if you really need the concept make it a factory method e.g.

MustInherit Class BaseForm

  MustOverride Sub GetForms()

End Class

Class MyForm
   Inherits BaseForm

   Public Sub New()
   End Sub

   Overrides Sub GetForms()
   End Sub   
End Class

Now you just need

Dim f as BaseForm = New MyForm
f.GetForms

Alternatively GetForms might be Protected and called from the Sub New.

Mark Hurd
Totally Agree. MyForm.GetForms() can operate only on the type MyForm and there is no way to specify the derived type form which need to be used.
Ramesh
It would be easy to distinguish, I would think, if I call something like `Invoice.GetForms()`, it would go to the shared 'GetForms()` method in the `Invoice` class... how is that difficult? In the base class, declare it as `Public MustOverride Shared Sub GetForms()`. Unfortunately, this won't compile... makes perfect sense to me that it should though...
Jason
@Jason, That's what I mean by it might as well just be documented as the intention: how is the code broken if the intended functionality was actually implemented by InvoiceOther.TheFormsGet().
Mark Hurd