views:

4548

answers:

8

My application reads an Excel file using VSTO and adds read data to a StringDictionary. It adds only data that is a number with few digits (1000 1000,2 1000,34 - comma is a delimiter in Russian standards).

What is better to check current string being appropriate number?

object data, string key; // data had read

try
{
  Convert.ToDouble(regionData, CultureInfo.CurrentCulture);
  dic.Add(key, regionData.ToString());
}
catch (InvalidCastException)
{
  // is not a number
}

or

double d;
string str = data.ToString();
if (Double.TryParse(str, out d)) // if done, then is a number
{
  dic.Add(key, str);
}

I have to use StringDictionary instead if Dictionary<string, double> because of following parsing algorithm issues.

My questions: which way is faster? is more safe?

And is it better to call Convert.ToDouble(object) or Convert.ToDouble(string) ?

+2  A: 

The .NET Framework design guidelines recommend using the Try methods. Avoiding exceptions is usually a good idea.

Convert.ToDouble(object) will do ((IConvertible) object).ToDouble(null);

Which will call Convert.ToDouble(string, null)

So it's faster to call the string version.

However, the string version just does this:

if (value == null)
{
    return 0.0;
}
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);

So it's faster to do the double.Parse directly.

Jeff Moser
+1  A: 

Double.TryParse IMO.

It is easier for you to handle, You'll know exactly where the error occurred.

Then you can deal with it how you see fit if it returns false (i.e could not convert).

Damien
+4  A: 

If you aren't going to be handling the exception go with TryParse. TryParse is faster because it doesn't have to deal with the whole exception stack trace.

Aaron Palmer
+3  A: 

I generally try to avoid the Convert class (meaning: I don't use it) because I find it very confusing: the code gives too few hints on what exactly happens here since Convert allows a lot of semantically very different conversions to occur with the same code. This makes it hard to control for the programmer what exactly is happening.

My advice, therefore, is never to use this class. It's not really necessary either (except for binary formatting of a number, because the normal ToString method of number classes doesn't offer an appropriate method to do this).

Konrad Rudolph
+1  A: 

I have always preferred using the TryParse() methods because it is going to spit back success or failure to convert without having to worry about exceptions.

TheTXI
+8  A: 

To start with, I'd use double.Parse rather than Convert.ToDouble in the first place.

As to whether you should use Parse or TryParse: can you proceed if there's bad input data, or is that a really exceptional condition? If it's exceptional, use Parse and let it blow up if the input is bad. If it's expected and can be cleanly handled, use TryParse.

Jon Skeet
Note that there is one more difference between `double.Parse` and `Convert.ToDouble` besides the obvious one that the first allows you to specify a culture whereas the second always uses the current culture: `Convert.ToDouble` internally calls `double.Parse` but with an additional null check. If you pass in `null` `Convert.ToDouble` will immediately return `0.0` whereas `double.Parse` will throw.
0xA3
+1  A: 

Personally, I find the TryParse method easier to read, which one you'll actually want to use depends on your use-case: if errors can be handled locally you are expecting errors and a bool from TryParse is good, else you might want to just let the exceptions fly.

I would expect the TryParse to be faster too, since it avoids the overhead of exception handling. But use a benchmark tool, like Jon Skeet's MiniBench to compare the various possibilities.

David Schmitt
+11  A: 

I did a quick non-scientific test in Release mode. I used two inputs: "2.34523" and "badinput" into both methods and iterated 1,000,000 times.

Valid input: Double.TryParse = 646ms Convert.ToDouble = 662 ms

Not much different, as expected. For all intents and purposes, for valid input, these are the same.

Invalid input: Double.TryParse = 612ms Convert.ToDouble = .. well.. it was running for a long time. I reran the entire thing using 1,000 iterations and Convert.ToDouble with bad input took 8.3 seconds. Averaging it out, it would take over 2 hours. O_o. I don't care how basic the test is, in the invalid input case, Convert.ToDouble's exception raising will ruin your performance.

So, here's another vote for TryParse with some numbers to back it up.

siz