Code Focused

C# and VB Data Conversion in a World of Cruel Users

While Visual Basic is a bit more forgiving with data conversions, you'll need to jump through some hoops to do similar conversions in C#.

Although my programing career began in the rough and tumble of the C language, I spent many years safe in the gentle embrace of Visual Basic. The buffer overruns and dangling pointers of my turbulent C years gave way to easy string manipulation, single-line file and input processing methods, and the all-forgiving On Error Resume Next statement.

These days, I'm back in the C family thanks to C# and the .NET Framework. But I do miss the coddling at times, especially when it comes to processing and converting user-supplied content. Users can be brutal with data. It's almost like they plan their lives around crashing my programs. Is it my fault that you live at 123-1/2 Main Street? I mean, who ever heard of house numbers than end in "and a half"? That's crazy, right?

Two of the features I miss most from Visual Basic are conversions from money strings to true numeric values, and the Val function, which also processes string-embedded numbers. The money conversion feature understood that no two users are alike, and that when confronted with the prompt, "How much money would you like to donate to the programmer?" they might respond using a variety of number formats:

amount = CDec("12000")       ' Converts to 12000
amount = CDec("$12,000.00")  ' This one, too

C# is not so accepting in its standard conversions:

amount = Convert.ToDecimal("12000");      // This works
amount = Convert.ToDecimal("$12,000.00"); // But not this
amount = (decimal)"12000";                // Doesn't even compile

Fortunately, the .NET Framework does include additional conversion features that understand things like money. The decimal.Parse method, for example, when paired with the System.Globalization.NumberStyles enumeration, handles financial input, taking into account the local currency symbol and regional digit separators:

// ----- Assumes: "using System.Globalization;"
amount = decimal.Parse("$12,000.00", NumberStyles.Currency);

The NumberStyles enumeration has lots of fun members, including more granular options for currency values (AllowCurrencySymbol and AllowThousands, among others), options for numbers entered in scientific notation (AllowExponent), support for whitespace (AllowLeadingWhite and AllowTrailingWhite), and variations that mask for integers, floating point values, and even hex digits:

// ----- Still returns 12000, though as int
int amount = int.Parse("2EE0", NumberStyles.HexNumber);

That other Visual Basic feature I still pine for is Val, which extracts the first valid number from a text string, ignoring any whitespace encountered along the way. Val had a calm way of dealing with multifaceted user input, returning zero when it didn't recognize things:

' ----- These both return 5
amount = Val("5")
amount = Val("    5 dollars   ")

' ----- But these return 0 (zero)
amount = Val("")
amount = Val("sdjkfjsadklsal")

These conversions are nice, though sometimes the function was a little too loose with the whitespace rule:

' ----- This produces 12345, but probably shouldn't
amount = Val("12   3     45")

If I'm going to endow C# with a Val-like method, I can make it as exacting as I want. One possible implementation uses regular expressions to grab the first decimal it finds, ignoring initial whitespace and anything that follows:

// ----- Assumes "using System.Text.RegularExpressions;"
private double Val(string source)
{
  string initialNumber;
  double result;

  // ----- Locate the text number.
  if (string.IsNullOrEmpty(source))
    return 0D;
  initialNumber = Regex.Match(source, @"^\s*(\d+\.?\d*)").Value;

  // ----- Attempt conversion.
  if (double.TryParse(initialNumber, out result))
    return result;
  else
    return 0D;
}

Of course, a data management purist would insist that users enter data correctly, giving them a stern rebuke when anything looks amiss. But such inflexibility leads to Web sites that refuse to automatically strip out punctuation from user-entered phone numbers, and that's just wrong. When you're feeling in a forgiving mode, you might want to look to Visual Basic and its caring ways for guidance.

About the Author

Tim Patrick has spent more than thirty years as a software architect and developer. His two most recent books on .NET development -- Start-to-Finish Visual C# 2015, and Start-to-Finish Visual Basic 2015 -- are available from http://owanipress.com. He blogs regularly at http://wellreadman.com.

comments powered by Disqus

Featured

Subscribe on YouTube