0

In my app, I have the following line:

double val = Convert.ToDouble(values8[x]) + 24837;

If values8[x] can't be converted to a Double the app crashes with the error Input string was not in a correct format.

How do I test this, and set val to DBNull.Value if the conversion fails? With a try/catch? Would something like this be acceptable?

EDIT: Here's what I'm trying to do

try 
{
    double val = Convert.ToDouble(values8[x]) + 24837;
    com.Parameters.Add("@p1", OleDbType.Date, 255).Value = DateTime.FromOADate(val);
}
catch (exception e)
{
    com.Parameters.Add("@p1", OleDbType.Date, 255).Value = DBNull.Value;
}

EDIT2: TryParse is what I was looking for.

Jeff Brady
  • 1,454
  • 7
  • 35
  • 56

3 Answers3

5

You'd better use the double.TryParse method instead of try and catching which could be more expensive:

double val;
if (double.TryParse(values8[x], out val))
{
    // you can safely use the val variable here
}
else
{
    // parsing failed
}

You also have the possibility to specify the culture if you know it in advance (you know thing like the decimal separator might be different for the different cultures, ...):

double val;
var culture = new CultureInfo("fr-FR");
if (double.TryParse(values8[x], NumberStyles.None, culture, out val))
{
    // you can safely use the val variable here
}
else
{
    // parsing failed
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • You should also mention nullables, as he wants to set the result to `DBNull.Value` in case of parse errors, which doesn't work. – Thorsten Dittmar Aug 22 '13 at 14:45
  • It's absolutely unclear from the question what does `DBNull.Value` has to do here so I preferred not to talk about it. – Darin Dimitrov Aug 22 '13 at 14:47
  • Is it really true that `TryParse` is less expensive than a manual `Try/Catch`? Does it not just use exception handling under the hood? – Rotem Aug 22 '13 at 14:48
  • I think from his code sample things are perfectly clear: He wants to make sure that `values8[x]` is a `double` and if it is not, set his `double` variable to `DBNull.Value`. That doesn't work, but nullables could be a solution here. – Thorsten Dittmar Aug 22 '13 at 14:48
  • 1
    @Rotem I remember that this has been discussed in lengths already somewhere, the main argument being that exceptions should not be used to control program flow, so `TryParse` is cleaner anyway. – Thorsten Dittmar Aug 22 '13 at 14:49
  • @Rotem Yes obviously why not give a try? – Sriram Sakthivel Aug 22 '13 at 14:49
  • @ThorstenDittmar It is definitely 'cleaner'. I was asking if it's also faster. – Rotem Aug 22 '13 at 14:50
  • 2
    @Rotem http://stackoverflow.com/questions/150114/parsing-performance-if-tryparse-try-catch – Thorsten Dittmar Aug 22 '13 at 14:51
  • 2
    @Rotem No, `TryParse` does not catch exception under the hood. `Number::ParseNumber` is actually parsing string (anyway, since `Numer` is internal class in `mscorlib.dll` it's implementation detail that may changed). – Leri Aug 22 '13 at 14:53
  • @Rotem, yes, it's faster. Throwing and catching is much slower. – Darin Dimitrov Aug 22 '13 at 14:53
  • I updated my question with a better idea of what I was trying to do with the `DBNull.Value` – Jeff Brady Aug 22 '13 at 14:54
  • 1
    Great, so there you go, in the `else` part of my code you could use `DBNull.Value` exactly as you did in your `catch` statement. It's just that using the `TryParse` method is faster than trying and catching. – Darin Dimitrov Aug 22 '13 at 14:55
  • 1
    @Rotem In fact if You use ILSpy to look at the source, The Try version and the non Try version call do the exact same steps except the try version has a `return false` and the non Try version has a `throw new FormatExecption` and throwing a exception will always be slower than just returning false. – Scott Chamberlain Aug 22 '13 at 14:58
1

double has a TryParse method that should be used. if parsing is successful than val will get value, else value will not be assigned to val. No exception will be thrown

double val;

if(double.TryParse(values8[x], out val))
{
     Console.WriteLine("Parsing successful");
}
else
{
   Console.WriteLine("Parsing failed");
}
Ehsan
  • 31,833
  • 6
  • 56
  • 65
1

According to your edit you need this:

double val;

if (!Double.TryParse(values8[x], out val))
   com.Parameters.Add("@p1", OleDbType.Date, 255).Value = DBNull.Value;
else
   com.Parameters.Add("@p1", OleDbType.Date, 255).Value = DateTime.FromOADate(val + 24837);
Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139