Different datatypes, same accessor

  • Thread starter Thread starter AAJ
  • Start date Start date
A

AAJ

Hi all

I would like to have a class that can set/return values of different
datatype via a single accessor, i.e. overload the accessor

i.e. something like

DateTime m_DateValue;
string m_StringValue;

public string Value
{
get { return m_StringValue; }
set { m_StringValue = value; }
}
public DateTime Value
{
get { return m_DateValue; }
set { m_DateValue = value; }
}

so I can use something like

ValueHandler testDate = new ValueHandler();
testDate.Value = "1/1/2006";
DateTime returndate = testDate.Value;

As well as

ValueHandler testString = new ValueHandler();
testString.Value = "My test String";
string returnString = testString.Value;

i.e. depending on the datatype, I can use the same accessor to store in
either a DateTime field or a string field

is there anyone who knows how to do this

thanks

Andy
 
I don't think you can do this, not least because it would result in a getter
that varies only by return type; while the CLR supports return-type
overloading, C# does not, or it wouldn't know what to do here:

object val = testDate.Value; // what type to use?

Similarly, you can't (IIRC) use generics in properties.

So either you need different names, or you could use (for string) the far
more common .Parse(string) and .ToString() pair.

Marc
 
The problem you are seeing is that the properties are being expanded by the
compiler to:

string GetValue();
SetValue(string);

DateTime GetValue();
SetValue(DateTime);

The Set methods are not too much of a problem as C# follows C++ overloading
rules and allows for methods to have the same name but different types of
parameters.

The Get methods however only differ by return value and therefore are seen
to be the same method. Incidently the CLR does support methods having the
same name but a different return value it's just that the language doesn't
for a variety of reasons.

Based on the code below if this class is to be used then having two fields
holding the same value is probably asking for trouble (normalisation of data
etc.).

If the class is wrapping a DateTime then I'd suggest:

1. Only contain a DateTime field; lose the string.
2. Use the Value accessor to get/set the DateTime value (or possible use
conversion operators see below).
3. Use ToString to convert the DateTime to a string.
4. Either add a SetValue(string) and parse the string into the DateTime
field or look into using conversion operators (see
http://windowssdk.msdn.microsoft.com/en-us/library/85w54y0a.aspx).

HTH

- Andy
 
"AAJ" <a.a.com> a écrit dans le message de %[email protected]...

| I would like to have a class that can set/return values of different
| datatype via a single accessor, i.e. overload the accessor

This is not a good idea as it can cause confusion, unless you expressly name
the proeprties differently or perhaps, if you are using VS2005, use
generics.

public class ValueHandler<typeT>
{
private typeT value;

public typeT Value
{
get { return value; }
set { this.value = value; }
}
}

{
ValueHandler<string> testString = new ValueHandler<string>();
testString = "My test String";
string returnString = testString.Value;
}

....or...

{
ValueHandler<DateTime> testDate = new ValueHandler<DateTime>();
testDate = DateTime.Parse("1/1/2006");
DateTime returnDate = testDate.Value;
}

Joanna
 
Thanks all for the rapid answers!!!

the genreal consensus is its not the way to go...

I just started typing a long winded reply with full details of my problem,
but as so often happens when you stop and think, an alternative solution
popped into my head.

It turns out I can use an inherited Abstract base class to form a structure,
and overide the bits I need for managing the type conversions

thanks again for all the replies

Andy
 
AAJ,

Nice you found it, but I am curious about the sence, can you explain that to
us?

Cor
 
Hi Cor

The class was needed to provide an easy to use standard, for seperating the
GUI and the Database, so the GUI layer was totally removed from the business
layer and the database layer.

Its a bit more involved but in essence, the class needed to hold a value, a
fieldname, a flag to say an update was required and a method to prepare
itsself in a common way for one of a standardised stored procedure. One
stored procedure handles DateTime updates, another VARCHAR updates, another
Decimal (for currency) etc...

The objects created needed to be of a common base, so I could easily add to
an array list, meaning I could use foreach.. if myclass.changereq = true
then ...UpdateDatabase()

My initial thought (and post) was to overload the accessors, so If the
stored value was a DateTime, UpdateDataBase() would return Value and get its
base class variable and the over loading would know to return a DATETIME
value, Varchar with a string etc...

After reading the replies, it seemd it couldn't be done other than by
converts and object classes.

However, It turned out to be easy when I thought about it ( I should have
been more carefull at the start!), all I needed was a class that I could
inherit from my base class that had UpdateDataBase(), change pending etc
defined. The inherited classes overrode UpdateDataBase() method, and used
their own variable types.

so I have base class --> UpdateDataBase()

then I inherit from it for say a

DateManager class, that has its own Dataype Value of DateTime plus an
overridden UpdateDataBase()
a StringManager class, that has its own DataypeValue of String plus an
overridden UpdateDataBase()

it was easy to add each object to an ArrayList and when I need to update I
can use foreach, check the Update required, flag, and then call the
UpdateDatabase flag

worked a treat

I'm new to C# and OOPS so things that used to come easily, I now have to
think about much more, so thanks again everyone who responded

Andy
 
You mention ArrayList, so I guess you're using 1.1 - but note that this
would be an ideal candidate for generics in 2.0 - so your DateManager
and StringManager would become simply Manager<DateTime> and
Manager<string>, and you only need to write the code once. The generic
class can still talk happily to the non-generic database code, but it
means your items are a: type-safe and b: only boxed at the final step,
and not before.

The only thing you might need to do would be a simple parameter-type
converter (for the DbType)...

Marc
 
AAJ,

Thanks for your explanation,

Cor

AAJ said:
Hi Cor

The class was needed to provide an easy to use standard, for seperating
the GUI and the Database, so the GUI layer was totally removed from the
business layer and the database layer.

Its a bit more involved but in essence, the class needed to hold a value,
a fieldname, a flag to say an update was required and a method to prepare
itsself in a common way for one of a standardised stored procedure. One
stored procedure handles DateTime updates, another VARCHAR updates,
another Decimal (for currency) etc...

The objects created needed to be of a common base, so I could easily add
to an array list, meaning I could use foreach.. if myclass.changereq =
true then ...UpdateDatabase()

My initial thought (and post) was to overload the accessors, so If the
stored value was a DateTime, UpdateDataBase() would return Value and get
its base class variable and the over loading would know to return a
DATETIME value, Varchar with a string etc...

After reading the replies, it seemd it couldn't be done other than by
converts and object classes.

However, It turned out to be easy when I thought about it ( I should have
been more carefull at the start!), all I needed was a class that I could
inherit from my base class that had UpdateDataBase(), change pending etc
defined. The inherited classes overrode UpdateDataBase() method, and used
their own variable types.

so I have base class --> UpdateDataBase()

then I inherit from it for say a

DateManager class, that has its own Dataype Value of DateTime plus an
overridden UpdateDataBase()
a StringManager class, that has its own DataypeValue of String plus an
overridden UpdateDataBase()

it was easy to add each object to an ArrayList and when I need to update I
can use foreach, check the Update required, flag, and then call the
UpdateDatabase flag

worked a treat

I'm new to C# and OOPS so things that used to come easily, I now have to
think about much more, so thanks again everyone who responded

Andy
 

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

Back
Top