views:

368

answers:

5

I have a bunch of different forms that I would like to create a base MustInherit class for. One function I would like them all to contain is a shared function called GetForms(). I know that you can't declare a shared function MustOverride so I did the following in my abstract class:

Public Shared Function GetForms() As List(Of OrderForm)
    'to be overridden in child class'
    Return Nothing
End Function

And this in my child class:

Public Overloads Shared Function GetForms() As List(Of OrderForm)
    'do stuff'
End Function

Will this cause problems down the line, or is this an acceptable workaround? It has a smell to it, but it will enforce that all my forms include a shared GetForms function.

EDIT I realize that if this were possible with interfaces, I would use one, but you can't declare shared functions in interfaces and I would like to make sure that this is a SHARED function.

Any help would be greatly appreciated. Thanks so much!

A: 

Yes, that does smell!

Looks like you should be using an interface instead.

Here is a vb.net article: http://www.developer.com/lang/other/article.php/939411

ScottE
you can't declare shared functions in interfaces
Jason
It looks like he wants to enforce classes to implement certain functionaly, which sounds like a good reason to use an interface.
ScottE
except I want it to be SHARED... and you can't declare a function as SHARED using an interface...
Jason
Could you explain why the methods must be shared? If they must, you can always use a helper function, like I've done in the past with a DAL and pluggable data access layer.
ScottE
let's say i have an order that consists of, say, 5 different types of forms. each order can have multiple forms for each type of form, so 3 for type 1, 5 for type 2, etc. Rather than have a "GetAllForm1", "GetAllForm2", I'd rather have a shared GetForms where I can just call it at the class level, say Form1.GetForms. This way the behavior is consistent throughout each form. Yes, I would love to use an interface, but it's simply not possible because you can't declare a shared function in an interface.
Jason
Well, why can't you have a parameter to the GetForms method that accepts the type of form. Does that help?
shahkalpesh
@shahkalpesh - but why pass a parameter when you can loosely couple a simple shared function? is there something explicitly wrong w/the way i'm doing things, or will this actually work? i'm a ways away from testing and it'd be nice if i could find out now if it's going to break...
Jason
A: 

Why wouldn't you simply declare it as:

Public MustOverride Function GetForms() As List(Of OrderForm)?
chris
because i need it to be shared...
Jason
+3  A: 

This has a smell because it creates a false expectation of the behavior of the code.

You mention that your reason for doing this is that 'it will enforce that all my forms include a shared GetForms function'. This is only partly true. Yes, they will all have the GetForms function, but you're not actually forcing the derived classes to implement their own version of it. If you forget to implement the function on one of them, you'll be calling the base version, and you won't get any sort of warning about it from the compiler.

That is the smell: it can't actually enforce the behavior that you want, but it creates an impression, at first glance, that it can. This will lead to headaches 6 months from now when you're adding a new Form type and you've forgotten the convention. You'll get no warning that something's wrong until you start getting bad results during testing.

If you want to enforce behavior, you have to do it using instance members; using MustOverride (abstract) functions or an interface.

Jeromy Irvine
yeah i've been futzing around with the code and realized that it doesn't actually enforce this. so basically, the only thing i can do is just remember to use the `GetForms()` function in every form. Wonderful.
Jason
on another note, is there any way to enforce the inheritance and overriding of a shared function? i can't seem to figure out how, and every resource i've looked at has told me no without any sort of workaround...
Jason
There's no language mechanism to allow forced overriding of shared members. The workaround is to rethink your design so the code that works with the forms either doesn't care what type they are, or to use helper functions, or perhaps factory to create handlers that can deal with each type of form as needed.
Jeromy Irvine
A: 

Static methods aren't inherited, so the expectation of overriding is not something we want to encourage. In other words, I think you might be barking up the wrong tree here.

Steven Sudit
+1  A: 

You can have static (Shared) methods like that, but you can't enforce the implementation of them.

Each static method is local to it's class, you can't overload it in a child class or make it abstract (MustInherit). You have to use an instance method (non-static) to get the object oriented aspects that you want.

Guffa