.NET Array Dictionary List String 2D Async DataTable Dates DateTime Enum File For Foreach Format IEnumerable If IndexOf Lambda LINQ Parse Path Process Property Regex Replace Sort Split Static StringBuilder Substring Switch Tuple

C#

Parse. Strings often contain data like integers or times. In computer programs, having an int is often more useful than a string. It can be tested in more ways.


With parse methods, like int.Parse, we convert strings into low-level types (like ints). We call Parse, TryParse and Convert.ToInt32. For times, we can use DateTime.Parse.


First example. We see the int.Parse method, which is the simplest one. Parse() throws exceptions on invalid input. This can be slow if errors are common.

Info: This is a static method we access on the int type. It returns an integer upon success.

Based on:

.NET 4.5

C# program that uses int.Parse

using System;

class Program
{
    static void Main()
    {
	// Convert string to number.
	string text = "500";
	int num = int.Parse(text);
	Console.WriteLine(num);
    }
}

Output

500

Errors. The int.Parse method is strict. With an invalid string, it throws a FormatException. We can catch this using a try-catch construct.

But: Using the int.TryParse method is usually a better solution. TryParse is faster.

C# program that encounters FormatException

using System;

class Program
{
    static void Main()
    {
	string input = "carrot";
	// ... This will throw an exception.
	int carrots = int.Parse(input);
	Console.WriteLine(carrots);
    }
}

Output

Unhandled Exception: System.FormatException:
Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, ...
   at System.Number.ParseInt32(String s, NumberStyles style, ...

TryParse. A useful method for parsing integers is the int.TryParse method. The parsing logic in TryParse is the same. But the way we call it is different.

But: TryParse uses somewhat more confusing syntax. It does not throw exceptions.

Tip: You must describe the second parameter with the out modifier. TryParse also returns true or false based on its success.

OutTrue, False

Null: TryParse never throws an exception—even on invalid input and null. It is overall preferable to int.Parse in most program contexts.

Performance: This method is ideal for input that is not always correct. When errors occur, performance is better.

C# program that uses int.TryParse

using System;

class Program
{
    static void Main()
    {
	// See if we can parse the 'text' string.
	// If we can't, TryParse will return false.
	// Note the "out" keyword in TryParse.
	string text1 = "x";
	int num1;
	bool res = int.TryParse(text1, out num1);
	if (res == false)
	{
	    // String is not a number.
	}

	// Use int.TryParse on a valid numeric string.
	string text2 = "10000";
	int num2;
	if (int.TryParse(text2, out num2))
	{
	    // It was assigned.
	}

	// Display both results.
	Console.WriteLine(num1);
	Console.WriteLine(num2);
    }
}

Output

0
10000

TryParse notes. We must use out before the second argument in int.TryParse. With "out", the compiler can help you make sure your variables are always in a valid state.

Parameters Ref, Out

Tip: It is useful to know that the word "int" in the C# language simply aliases the System.Int32 type.

Therefore: If you see code that uses "System.Int32.Parse" or "System.Int32.TryParse", it is equivalent to int.Parse and int.TryParse.


TryParse with no if. Usually we call int.TryParse inside an if-statement. But this is not required. And sometimes, we can just treat a failed parse as the default value (0 for int).

Tip: This removes a branch in our code—we can just use the result, not test it. Branches are good for trees, but bad for performance.

C# program that uses int.TryParse, no if

using System;

class Program
{
    static void Main()
    {
	string error = "Welcome";
	// This will leave the result variable with a value of 0.
	int result;
	int.TryParse(error, out result);
	Console.WriteLine(result);
    }
}

Output

0

Convert. Convert.ToInt32, along with its siblings Convert.ToInt16 and Convert.ToInt64, is actually a static wrapper method for the int.Parse method.

Static Method

Warning: ToInt32 can be slower than int.Parse if the surrounding code is equivalent.

Confusing: The syntax here may be more confusing. It uses the bit size of the int, which may not be relevant to the code's intent.

C# program that uses Convert.ToInt32

using System;

class Program
{
    static void Main()
    {
	// Convert "text" string to an integer with Convert.ToInt32.
	string text = "500";
	int num = Convert.ToInt32(text);
	Console.WriteLine(num);
    }
}

Output

500

TryParse versus Parse. When I first wrote about int.Parse, I recommended it as the best parsing option. After many years, I have changed my mind.

TryParse: I recommend using TryParse in most situations. It is faster on errors, and is a good default choice for parsing.

Also: In projects where speed is an issue (which is common), I take the time to add an optimized method like IntParseFast below.

Floating-point: If your input has many digits or decimal places use double.Parse or double.TryParse.


Other types. Numbers can be smaller than an int (like a byte) or much larger (like a decimal). Each type has a useful Parse and TryParse method.

decimal.Parsedouble.Parselong.Parse

Optimized algorithm. An optimized int.Parse method reduces computational complexity. It uses a for-loop on the characters in a string.

Note: This algorithm maintains the running total as it proceeds through the characters. It fails on nontrivial number strings.

ASCII: The method relies on the ASCII values of characters. The character "1" is offset +48 from the integer 1 in ASCII.

C# program that times int parse methods

using System;
using System.Diagnostics;

class Program
{
    public static int IntParseFast(string value)
    {
	// An optimized int parse method.
	int result = 0;
	for (int i = 0; i < value.Length; i++)
	{
	    result = 10 * result + (value[i] - 48);
	}
	return result;
    }

    const int _max = 1000000;
    static void Main()
    {
	// Test the methods.
	Console.WriteLine(IntParseFast("123456"));
	Console.WriteLine(int.Parse("123456"));

	var s1 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    int result = IntParseFast("123456");
	}
	s1.Stop();
	var s2 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    int result = int.Parse("123456");
	}
	s2.Stop();
	Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
	    _max).ToString("0.00 ns"));
	Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
	    _max).ToString("0.00 ns"));
	Console.Read();
    }
}

Results

123456
123456
  4.53 ns:    IntParseFast
116.67 ns:    int.Parse

Optimization notes. Above, our method converts a character like "1" to the integer 1. ASCII chars are stored in different positions than the equivalent numbers, but in the same order.

Info: The earlier a digit occurs, the more times it must be multiplied by 10 to correctly parse the number.

Next: As we read the string from the left to the right, the current digit is one tenth of the previous one.

Multiply: We can multiply the previous number by 10 to satisfy this condition. The 48 we use simply shifts ASCII digits to ints.


Low-level optimization. Think of how many different things int.Parse must deal with: negative numbers, decimals, null characters, letters, line breaks, spaces, colons and different locales.

And: We don't need all that every time. We just need to parse a series of characters and store it in an int or ushort.


DateTime. Parsing is fun. It is one of my passions in life. We can parse a string into a DateTime type with TryParse. Parsing methods on DateTime use a similar syntax.

DateTime.Parse

Note: The Parse and TryParse methods have separate implementations for each type. But they have a unified calling syntax.

C# that calls TryParse on DateTime

using System;

class Program
{
    static void Main()
    {
	string now = "12/22/2014";
	// Use TryParse on the DateTime type to parse a date.
	DateTime parsed;
	if (DateTime.TryParse(now, out parsed))
	{
	    Console.WriteLine(parsed);
	}
    }
}

Output

12/22/2014 12:00:00 AM

A long time ago, programmers would write their own integer conversion routines. This was complicated. It was redundant. These methods were prone to errors.


Parse, TryParse. With these method groups, the .NET Framework has built-in functionality. Many types, not just int, have Parse methods—we use them in similar ways.