ChangeType, Convert - Converting from one type to another
I've looked at the various options that seem to be available on the .NET framework (I think). In particular, I've looked at 1. TypeConverter 2. Convert.Toxxx 3. Convert.ChangeType
Each of them for one reason or another don't work for me. I'm quite surprised that there doesn't seem to be a solution in the .NET framework for this sort of thing. I'm assuming I'm not the only one who needs this ;)
Here is what I'm trying to do. Essentially, I've got a bunch of html forms that are used in an application. These forms allow users to enter data (obviously) and I need to extract this data into various data types.
These data types are simple types, primitive types, value types, reference types and custom reference types. In other words: 1. Int32, Int64, double, decimal, DateTime etc. 2. Int32[], double[], string[] and possibly other arrays of primitive types 3. various custom DTO objects that have the above types as properties.
The "input" is in the form of a string typically since I'm in Http land. To give you an idea of why the existing solutions don't work for me, take a look at the following "string" inputs that need converting
- "1,234" -> Int32
- "$1,234" ->Int32
- " $ 1,234 " -> Int32
- "" -> Int32
- "1,2,3,4,5" ->Int32[]
- "0" OR "false" OR "False" OR "off" -> Boolean false
I know how to convert each of these cases by hand, but I am looking for either s开发者_运维技巧omething that's part of the framework that I've missed or a decent solution that handle the types of inputs listed above.
Jackie,
This is a very common requirement in the Web Development world and as you've noted there is no built-in way to achieve this and what is there falls short in the simplest of cases.
@Chris these rules are not arbitrary by any shot of the imagination. They are in fact very common when it comes to dealing with user input, especially over the web. In fact the Boolean conversions are also pretty common given that check boxes in ASP.NET return on/off (for some reason).
You have a a couple of options. One is a simplistic approach and another an extensible solution. It all starts from the way you'd like to use this functionality from within your application. Since you've not shed a lot of light on what it is you are doing currently or how you'd like to do this, I've taken the liberty of making a few assumptions.
The primary assumption being that the values come to you via the Request.Form or Request.QueryStrings (both of which are NameValueCollections that can hold multiple values for a given name).
Let's assume you'd like a method called ChangeType that given a name of the parameters and the Type you'd like to change it to will return the value as the required type. So the method signature might look like this:
public T ChangeType<T>(string parameterName, T defaultValue = default(T))
And so you can use it like so:
int someId = ChangeType<int>("id", -1);
So the value of the variable someId will either be the value extracted from Request.Form or Request.QueryStrings in the form of an int (if it exists) or -1 if it does not.
A more complete implementation is as follows:
static T ChangeType<T>(string value) where T: struct
{
Type typeOft = typeof(T);
if (String.IsNullOrEmpty(value.Trim()))
return default(T);
if (typeOft == typeof(Int32))
return (T)ConvertToInt32(value);
else if (typeOft == typeof(Int64))
return (T)ConvertToInt64(value);
else if (typeOft == typeof(Double))
return (T)ConvertToDouble(value);
else if (typeOft == typeof(Decimal))
return (T)ConvertToDecimal(value);
return default(T);
}
static object ConvertToInt32(string value)
{
return Int32.Parse(value,
NumberStyles.Currency ^ NumberStyles.AllowDecimalPoint);
}
static object ConvertToInt64(string value)
{
return Int64.Parse(value,
NumberStyles.Currency ^ NumberStyles.AllowDecimalPoint);
}
static object ConvertToDouble(string value)
{
return Double.Parse(value, NumberStyles.Currency);
}
static object ConvertToDecimal(string value)
{
return Decimal.Parse(value, NumberStyles.Currency);
}
If you need to be able to handle more types, simply implement the required method (such as ConvertToInt32 for example) and add another else condition in the ChangeType<T>
method and you're done.
Now if you're looking for an extensible solution such that you can add additional capability without having to modify the primary code and be able ot handle your own custom types, then please take a look at this blog post of mine. [ChangeType – Changing the type of a variable in C#][1] http://www.matlus.com/2010/11/changetypet-changing-the-type-of-a-variable-in-c/
Hope this Helps.
All the primitive types such as int and bool have a TryParse static method that you can use for them. This will do your Int32 stuff for you:
Int32 temp = 0;
Int32.TryParse(myStringInput, out temp);
The TryParse()
returns a boolean indicating whether the parse was successful or not, so you can test for that and take action if you want to, or just do as i did above and have a default value if the TryParse
fails. The TryParse is particularly useful because it doesn't throw an exception if it fails (it just returns false
instead).
The bool.TryParse()
is not going to directly translate a numeric 0
as false
- you need to cast it to a string first:
bool x = true;
bool.TryParse(0.ToString(), out x);
Console.WriteLine("x is {0}", x);
Translating the string value off or on to a boolean will require your own function to interpret it.
精彩评论