Ho to inherit from a struct

B

Boaz Ben-Porat

I Know, ... a struct can not be inherited.
** Is there any tricky way to extend a struct ? **

I have to implement a component that represent a date (without time) that
has a small number of functions over those of DataTime type. My first thougt
was : "Inherit from DateTime and implement those functions". Then I found
out that DateTime is a struct, not a class, so it can`t be done.

For example, The new type should implement an overloaded '+' operator that
takes an integer instead of TimeSpan.

I can think of 3 models to accomplish the task:

1. Drop implemetation, use DateTime and force all other developers to learn
how to use it.
----------------------------------------------------------------------------
--------------

2. Define a class that implements a minimum extra functionality:
---------------------------------------------------------------
public class TDate
{
public DataTime theDate;

public TDate(DateTime t)
{
theDate = t;
}

public static TDate operator + (TDate t, int iDaysToAdd)
{
// Add 'iDaysToAdd' to member theDate
}
}

All other manipulations are done directly on the inner DateTime member, by
all developers.
** This is the same problem as first model. All developers must work with
DateTime directly ***

3. Define a class as in model 2, but let it implement ALL DateTime methods
in the form:

public <return-type> SomeMethod(<args>)
{
return theDate.SomeMethod(<args>);
}

*** This is a 'slave work' for the one who implements 'TDate' class , but
saves all others from working with DateTime.

Back to the main question: *** Is the a smarter way to do it ? ***

TIA
Boaz Ben-Porat
DataPharm a/s
Denmark
 
N

Nicole Calinoiu

Ben,

Some pros and cons against each of your approaches (as numbered in your
original post):

1. I can't see any real problem with "forcing all other developers to learn
how to use it". DateTime is not all that terribly complicated, and the
documentation is reasonably decent. If you think that, despite this, your
developers are going to have a problem with it, perhaps some training is in
order (regardless of what you do wrt this particular issue).

2. This is my personal least favourite of the three. Some problems:
a. It requires consuming developers to keep track of which functionality is
delivered via the wrapper class and which functionality must be directed
against the inner DateTime.
b. You lose any control over enforcing what _should_ be done against the
wrapper vs the inner object.
c. If you extend your outer class to take over more of the functionality
originally delegated to DateTime, how are you going to find the old calls
against the inner object in order to change them? The compiler can't help
you, so you'll need to resort to searching the source code. However, even
that could be ugly. e.g. (instead of a direct call via
foo.theDate.SomeMethod()):
TDate foo = new TDate(<some DateTime>);
DateTime bar = foo.theDate;
bar.SomeMethod();

3. This is pretty much the standard method for extending a sealed class.
It is the most work to implement if you're aiming for exposing the complete
functionality set offered by the original class. However, it gets rid of
all the problems described for approach #2 and, as such, is usually well
worth the extra work. That said, there are some things you can do to cut
down on this work:
a. Don't implement the full DateTime functionality set if you don't need
it. From you concern about the developer training issue, it sounds like you
might be worried that some of the DateTime functionality might get mis-used.
If so, don't expose it at all.
b. Find/buy/build a utility to build this sort of wrapper class with
default implementations of each "base" method and property that pass the
call directly to the hidden inner object. If you can't find one, building
it might take more time than just manually implementing your TDate class,
but you'll be able to re-use the utility, so it'll probably be worth the
extra time.

HTH,
Nicole
 
I

Ignacio Machin

Hi,

First of all you have to ask your self why are you doing this and if this
is really needed in this case, you mentioned two concerns in your post
1- You implied that the developers do not know how to use DateTime
2- The new type should implement an overloaded '+' operator that takes an
integer instead of TimeSpan.

So here are my thoughts:
1- The DateTime struct is not that complicated and is widely used in the
framework, if anybody is going to work with the framework it definely needs
to know how to handle DateTime structs. so if you are concerned if they are
not going to learn how to use it, I would schedule some training first !!!
2- This would be the the sole reason to do what you want, if you have to
have this functionality then you have to wrap the DateTime struct.


Now of the three options I would go for the 3rd one, It's a Adapter pattern
and is also the preffered method of extend a sealed class.


Hope this help,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top