简体   繁体   中英

How to properly use decimal.TryParse and decimal.Parse

I have method in which I try to parse string to decimal number. At first I implemented the method with decimal.Parse and wrapped the body of the method in try catch block. Then I threw exception in catch block when the Parse method had thrown FormatException. I know it's not a good practice to throw exception in a catch block, but I couldn't figure out how to add detailed info about the parsing error. Then I refactored the method to look like this:

public List<ExcelGeneralLedgerRow> ParseGeneralLedger(DataTable worksheet)
        {
            var rows = new List<ExcelGeneralLedgerRow>();
            for (int i = 1; i <= worksheet.Rows.Count - 1; i++)
            {
                var row = worksheet.Rows[i];

                if (!decimal.TryParse(row[3].ToString(), out decimal value))
                {
                    throw new Exception($"detailed info about that exception was thrown on specific row.");
                }

                var syntheticAccountNumber = row[0].ToString();
                var analyticAccountNumber = row[1].ToString();

                if (analyticAccountNumber == String.Empty)
                {
                    analyticAccountNumber = "000";
                }

                var text = row[2].ToString();
                rows.Add(new ExcelGeneralLedgerRow(syntheticAccountNumber, analyticAccountNumber, text, value));
            }

            return rows;
        }

is this a good practice? it seems to me that with this approach I can add more information to the thrown exception. also i can parse more than just one value and add information about which parsing failed. but the code would fast turn to spaghetti code if I implement numerous if statements to throw exception.

Whats your opinion? Is there any other approach?

Thanks.

As was answered by Johnathan Barclay, there is nothing that would limit you from throwing from inside a catch block. There is even a way to catch and rethrow the original exception like this:

try {
   // Do something here that throws exception
} catch(Exception ex) {
   // log the exception
   throw;
   // instead of throw ex; which would reset the information of the original exception
}

You code, while there is nothing wrong with it, would benefit from a more specific Exception. Hence, custom exceptions

class GeneralLedgerParseException : Exception
{

    // Properties with the additional information
    public string //...

    public GeneralLedgerParseException()
    {

    }
}

This way you can even create catch clauses for the specific exceptions and handle them, without catching other generic exceptions.

try {
  //
} 
catch (GeneralLedgerParseException glex) {
  // Any other kind of exception will not be caught here
} 
catch (Exception ex) {
  // All other exceptions will be caught here
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM