5

I need to execute a lot of statements, one after the other, and I need that when a sigle statement throws an exception the flow of the program continues executing the next statement, for example:

double a = Double.Parse("2.5");
double b = Double.Parse("ADFBBG");
Geometry g = Geometry.Parse("M150,0L75,200 225,200z");

All statements have to be executed, so I need a sort of try-catch blocks in cascade:

double a, b;
Geometry g;

try
{
   a = Double.Parse("2.5");
}
catch
{}

try
{
   b = Double.Parse("ADFBBG");
}
catch
{}

try
{
   g = Geometry.Parse("M150,0L75,200 225,200z");
}
catch
{}

Obviously this is not the most elegant way to write my program. Is there a better way (more elegant, that does not reduce significantly the performance)?

I tried using the Func<TResult> delegate in such a way:

I wrote the following method:

T Try<T>(Func<T> func)
{
    try
    {
        return func();
    }
    catch
    {
        return default(T);
    }
}

So I can use it like this:

double x = Try(() => Double.Parse("77"));
Geometry g = Try(() => Geometry.Parse("M150,0L75,200 225,200z"));

Other solutions?

gliderkite
  • 8,828
  • 6
  • 44
  • 80
  • What is supposed to `a`, `b` and `c` if any of the conversions fails? i.e. will they be left unassigned? – O. R. Mapper Nov 03 '13 at 10:35
  • 8
    I hope that your problem is not really based on the parsing of strings to doubles, because, you know, you could simply bypass the exception raising problem using TryParse instead of Parse. – Steve Nov 03 '13 at 10:37
  • 1
    @Steve Of course it is not.. – gliderkite Nov 03 '13 at 10:38
  • 1
    @O.R.Mapper If the "conversion fails" (i.e. the statement throws an exception) the variable has to be initialized with its default value. – gliderkite Nov 03 '13 at 10:39
  • 8
    You need a better example, or all you'll get is `TryParse` answers. :-) – John Saunders Nov 03 '13 at 10:44
  • @JohnSaunders You're right... I edited my question. – gliderkite Nov 03 '13 at 10:47
  • 6
    Your Try function is a good solution. Go with that. – David Arno Nov 03 '13 at 10:57
  • 2
    +1 for Try function. That is best solution i guess, go with that. – Rohit Vats Nov 03 '13 at 11:03
  • Can this be an option? http://stackoverflow.com/questions/2961656/generic-tryparse – Rubens Farias Nov 03 '13 at 11:04
  • Or this: http://madreflection.originalcoder.com/2009/12/generic-tryparse.html – Rubens Farias Nov 03 '13 at 11:09
  • If you're worried about the performance overhead of catching the exceptions, you'll have to make sure that all procedures you use (i.e. also `Geometry.Parse`, whatever that is) also comes with a version that doesn't use exceptions (for example, it could return `null` on failure). Maybe the libraries you use are open source? On one of the ~100 exception guidelines on MSDN, I've read that MS recommends that a program should not throw any exceptions during *normal execution* (even though the .NET doesn't even comply with that, so take that with a grain of salt). – dialer Nov 03 '13 at 11:19

4 Answers4

0

Use Double.TryParse.

It returns a value indicating whether the conversion was successfull. So you can use it the following way:

double converted;
bool success = Double.TryParse(value, out converted);

if (success)
{
    // Do whatever you want
    // The converted value is in the variable 'covnerted'
}
Andy
  • 3,997
  • 2
  • 19
  • 39
0

It seems that you don't care about which parse failed but just need a default value is case of failure? If so init your vars first to defaults then parse in a single try-catch:

double a=0.0, b=0.0;
Geometry g = new Geometry();

try
{
   a = Double.Parse("2.5");
   b = Double.Parse("ADFBBG");
   g = Geometry.Parse("M150,0L75,200 225,200z");
}
catch
{
    //At least mark that conversion was not succesful
}

Try-catch will only give you a performance hit when an exception is thrown. If all is well the impact of try-catch is minimal. see this question A bit more elegant then your posted code but at least more concise.

Alternative with using TryParse

double a=0.0, b=0.0;
Geometry g = new Geometry();

Double.TryParse("2.5", out a);
Double.TryParse("ADFBBG", out b);
Geometry.TryParse("M150,0L75,200 225,200z", out g);

But there is a caveat: Geometry doesn't has TryParse implemented... (assuming that you use System.Windows.Media.Geometry)

That brings me to the point:

  • use your Try<> func, doens't reduce overhead but is clean
  • validate the string first. Removes the overhead of try but introduces runtime overhead on parsing.

Either way: validating userinput has it costs.

In answer to the main question: How to properly put statements inside a try-catch block? If you don't care about which statement fails: 1 try-catch.

However: If the first statement fails, the other statement won't get executed. But, your system is already in in failed/corrupted state. Would further processing result in a correct result? (doubt it)

Community
  • 1
  • 1
lboshuizen
  • 2,746
  • 17
  • 20
-1

TryParse is more preferable, because you've no performance penalty on throwing and catching exception.

And one more inaccuracy in the above code - no difference between parsed "0" and default(T).

Code's more fast than yours

public static class StringExt
    {
        public static double ParseDouble(this string value)
        {
            double result;
            Double.TryParse(value, out result);
            return result;
        }

    }
sh1ng
  • 2,808
  • 4
  • 24
  • 38
-1

I have answered a similar question a few days ago. If you have a collection of string values, you can use the power of extension methods to do just that.

static public IEnumerable<double> ConvertToDouble(this IEnumerable<string> source)
{
    double x = 0;
    var result = source.Where(str => Double.TryParse(str, out x))
                        .Select (str => x);

    return result;      
}

So put everything in a collection and use .AsEnumerable() followed by ConvertToDouble() extension method. Everything which cannot be parsed, will be ignored without an exception and the result is of type IEnumerable<Double>

Original answer: Convert List<string> to List<int> in C#

/edit: does the downvoter care to explain? The OP has not clarified, why he wants to use try catch and has not explained what has to be done in case of an exception. Hance I assume he does not want to do anything in case an exception is raised.

Community
  • 1
  • 1
Marco
  • 22,856
  • 9
  • 75
  • 124