Number type conversion

P

Pavils Jurjans

Hello,

I am somewhat lost in the implicit/expicit possible/impossible type casting
in C#...

I need to write a class, which among other things, must have wat to read a
numeric value type, and internally convert it so that it could be saved in
database as real number (float). I plan to provide property(set) interface
for reading the value.

I have counted 11 types that are "numeric" in nature. Maybe there are more,
I don't know:

SByte
Int16
Int32
Int64
Byte
UInt16
UInt32
UInt64
Decimal
Double
Single

Obviously, it makes sense to long for a single property, that takes object
type and then knows what to do with it. Alternative could be writing
separate 11 properties for all the numeric types, that sounds like good
waste of time and code.
What I am sort of looking for, is the most correct way to do the two
following things:

1. Validate if the input is numeric.
my present approaches are:
1.1. Check if the value is a mamber of any one of the types:
if (value is SByte || value is Int16 || value is Int32 ... ) { proceed }
1.2. Do it in another way:
switch(value.GetType()+"")
{
case "System.Int16":
case "System.Int32":
case "System.Int64":
case "System.UInt16":
case "System.UInt32":
case "System.UInt64":
.....
proceed
}

2. Once we discovered that value is number, must convert the value to Double
1.1. Use implicit conversion:
Possible only in case if I have different properties for different number
types
1.2. Use explicit conversion:
int i = 100;
object o = i;
double d = (double) o; // throws error "Specified cast not valid", although
double d = (double) i; works smoothly.
1.3 Use Convert.ToDouble(value)
Seems that this works quite well. But, perhaps that is not the "fastest"
way?

Thanks for help,

Pavils
 
S

Stoitcho Goutsev \(100\)

Pavils,

There is no IsNumeric or something like that method or property anywhere but
you can use Type.IsPrimitive that will return true for all primitive types
which are all numerics (except Decimal) + Char. so you can save some typing.
BTW VB has some function called IsNumeric, so if you don't use VB you can
use the reflector tool to see how it's implemented. It does more than you
need though.

Converter class can convert only types the implement IConvertible interface,
which are all primtive types.

I don't know why you worry so much about performance, but I needed to do
something like this and what I did was
TypeConverter conv = TypeDescriptor.GetConverter(...)
if(conv != null && conv.CanConvertTo(typeof(double))
{
double dblVal = (double)conv.CovertTo(..., typeof(double));
}

I believe it is slower than Converter.ToDouble, but it works with all
primitive types and doesn't throw exceptions if the conversion is not
possible.
 
J

james.curran

Let's take a step back.

Where are these numbers coming from? Does a line that reads them look
like this:
int N = ReadFieldInt("Num");
or are they all like this:
object obj = ReadField("Num");

And if the latter, is ReadField() taking different types and forcing
them all into an object?

The reason I ask these questions is:
a) Doing the type identification at run-time is a slow & fragile
process.
b) Doing it at compile-time is fast & safer.
c) It's a virtual certainty that you already know what the data type
is. (for example, if they are being read from a database, the database
clearly knows what type they are. And if you are reading a particular
field, you know if that fields is a string or a number.)
 
P

Pavils Jurjans

Hello, James,
Let's take a step back.

Where are these numbers coming from? Does a line that reads them look
like this:
int N = ReadFieldInt("Num");
or are they all like this:
object obj = ReadField("Num");

And if the latter, is ReadField() taking different types and forcing
them all into an object?

The reason I ask these questions is:
a) Doing the type identification at run-time is a slow & fragile
process.
b) Doing it at compile-time is fast & safer.
c) It's a virtual certainty that you already know what the data type
is. (for example, if they are being read from a database, the database
clearly knows what type they are. And if you are reading a particular
field, you know if that fields is a string or a number.)

I understand you point - in my case, I am writing a solution that indeed
saved the data in the database in real type, and it is the type that is
returned in the property {get}, but I want to make interface more friendly
for the user of the class, and provide the property {set} with code that is
ready to accept all possible numeric types - so that the user of the class
doesn't have to bother about fat type-casting and converting code.

Regards,

Pavils
 
N

Nick H

I have no idea why you are messing with this - if you declare your
property as double then all the other types will be implicitly
converted (except decimal).

I would have thought Int64 and Uint64 would require an explicit
conversion since you potentially have loss of precision but apparently
not.
 
J

james.curran

How 'bout, instead of a property with a setter, an overloaded set
method:

void Set(Int32 v) {......}
void Set(float f) {.....}

etc.
 

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