|
ms
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Number type conversionI 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 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. -- Show quoteHide quoteHTH Stoitcho Goutsev (100) "Pavils Jurjans" <pav***@mailbox.riga.lv> wrote in message news:uVI1vPsaGHA.3976@TK2MSFTNGP02.phx.gbl... > 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 > 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.) Hello, James,
Show quoteHide quote > Let's take a step back. I understand you point - in my case, I am writing a solution that indeed > > 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.) 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 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.
Other interesting topics
Memory leak in C#
Exception .net activex loaded with axhost C# Client browser, cookies enabled? Hashtable - Order of storage Is a cast to string always possible without exception? polish character.dbf VFP6.0 -CSharp VS2003 Project fails to load after changing the name of the project folde What is C# equivalent of Delphi's ClientDataSet ? Post XML from one C# web app to another How to SELECT FROM In-Memory dataset in C# .NET? |
|||||||||||||||||||||||