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

  • Creating Reactive Applications in .NET

    In modern applications, data is being retrieved in asynchronous, real-time streams, as traditional pull requests where the clients asks for data from the server are becoming a thing of the past.

  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

  • .NET 9 Preview 3: 'I've Been Waiting 9 Years for This API!'

    Microsoft's third preview of .NET 9 sees a lot of minor tweaks and fixes with no earth-shaking new functionality, but little things can be important to individual developers.

  • Data Anomaly Detection Using a Neural Autoencoder with C#

    Dr. James McCaffrey of Microsoft Research tackles the process of examining a set of source data to find data items that are different in some way from the majority of the source items.

Subscribe on YouTube