5

I've got a with 1.1 build system here using Parse for converting values (now it's 3.5).

string myString = String.Empty;
double myValue = double.Parse(myString);

throws a FormatException (I expected 0.0).

If I rewrite that using 2.0+

string myString = String.Empty;
double myValue;
if (double.TryParse(myString, out myValue))
    //do something

I get the wanted 0.0, but unfortunately I lose the possibility to get a meaningful error message (in the else tree).

Why is giving me Parse an error and TryParse my expected value? Is there any way to get the error message out of TryParse (time is not the problem)?

I don't want to work around it like that:

  • Avoid the error using if...then

    myValue = myString.Length == 0 ? 0.0 : double.Parse(myString);
    
  • Two Calls if an error occured

    if (!double.TryParse(myString, out myValue))
        myValue = double.Parse(myString);
    
2
  • 3
    How is “Input string was not in a correct format.” a “meaningful error message”? Commented Dec 19, 2012 at 13:32
  • 1
    What's wrong with it? An empty string is not a valid double number. How much more detail in the error message do you expect? Commented Dec 19, 2012 at 13:35

7 Answers 7

8

Parse throws an exception if the string cannot be be parsed and TryParse returns a bool. You can handle this bool (true if the parsing was successful, else false) to display the success/error message you want to show.

Since myValue is an out parameter it has to be set by the method so, if the string cannot be parsed, TryParse sets it as 0.0 which is why you're getting that number when using the TryParse method.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm pretty sure that you are not describing the internal behavior correctly, and that there is no internal try/catch when you TryParse numbers.
Argh you are right the bool is returning false, thought it was true.
One way of implementing this is internal static bool Parse (string s, NumberStyles style, IFormatProvider provider, bool tryParse, out double result, out Exception exc) and using that in both Parse() and TryParse() (that's how it's implemented in Mono). Creating the exception object is not a problem, but throw/catch'ing it would be expensive.
2

No, it is not possible to get the exact error message. You only want to know if it is possible to convert to double and the result, if it is possible. The exact reason why the conversion fails is hidden from you.

Comments

2

TryParse allows you to convert without throwing exception and returns true if successful. The action you take depends on you

if (!double.TryParse(myString, out myValue))
{
//throw exception here
}

It is useful when you are not sure if input will always be numbers

4 Comments

How will I know which type of exception occurred?
@UNeverNo What exactly do you mean? What other information do you need to know beyond "This is not convert-able to a double." that the false return value gives you?
FormatException. You don't even need to know anymore 'cos false means the conversion did not succeed. Just tell your UI that value is not supported
@UNeverNo: no exception happened and even if it happened internally, TryParse should have 'digested' that exception to a boolean 'false' for you. the point in 'TrySomething' methods is that they should get their job done without allowing 'digestible' exceptions to reach our "boolishly-flowing" blood.
1

Why is giving me Parse an error and TryParse my expected value?

Because that's the way the interface is designed. TryParse does not throw an exception if the input has an invalid format. Instead it returns false.

Is there any way to get the error message out of TryParse (time is not the problem)?

No, but you can make your own error message.

if (double.TryParse(myString, out myValue))
{
    //do something
}
else
{
    throw new FooException("Problem!");
}

But if you want to throw an exception when there is an error it's simpler to just use Parse.

1 Comment

You're right, too. I thought TryParse was returning true for String.Empty.
0

TryParse is implemented somehow like this:

try
{
    Parse(...);
    return true;
}
catch
{
    return false;
}

So you can do it just the same way:

try
{
    double.Parse(str, out dbl);
}
catch (Exception ex)
{
    // Do something with ex.Message
    dbl = 0.0;
}

// Continue with dbl.

2 Comments

That would be a very inefficient implementation, throwing and catching exceptions is expensive. It's more likely the other way around.
Of course I agree, that you should not use exceptions in logic and that the implementation is terrible. I wouldn't use it, either. But when stating this answer I was referring to his comment "time is not a problem". This is just an answer - if it makes sense or not is the desicion of the asker. ;)
0

Forget double.TryParse, as it won't tell you (by design) why the parsing failed. Do it The Old Way:

string myString = String.Empty;
double myValue = 0.0;

try
{
    myValue = double.Parse(myString);
}
catch (FormatException)
{
    // Now you have a meaningful story here!
}

Comments

0

Out parameters has to be set, therefore if TryParse fails it will initialize the output to it's default before it returns, however you will and in the "else" loop... Meaning it failed...

Try running the code below, that will show you that TryParse actually overwrites the value, yet indicates that the parse fails...

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                ParseAndOutput("");
                ParseAndOutput("1.0");
                ParseAndOutput("ABC");
            }

            private static void ParseAndOutput(string input)
            {
                double value = -1;
                if (double.TryParse(input, out value))
                {
                    Console.WriteLine("Parse succeeded for '"+input+"', try parse changed to: " + value);
                }
                else
                {
                    Console.WriteLine("Parse failed for '" + input + "', try parse changed to:  " + value);
                }
            }
        }
    }

So both Parse and TryParse fails on string.Empty, they just report that failure differently which is the whole point of TryParse, it is never meant to throw an exception...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.