C# how to convert a string to int
Tags: dotnet, dotnetcore, csharp
Published: 2021-08-04 06:07:02

---
title: C# how to convert a string to int
published: true
description: Get all the details about how to convert a string to int with C#. Learn how to handle exceptions and all of the worst practices that everyone is doing.
tags: dotnet, dotnetcore, csharp
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6b10b2pbuans09fepxh.png
canonical_url: https://blog.elmah.io/csharp-how-to-convert-a-string-to-int/
---

Time for a new post in my [how-to series](https://blog.elmah.io/tag/how-to/). In this series, I try to provide updated answers for common .NET/C# questions. I found that when googling common terms like "convert string to int", "write to a file", and similar, I would often get outdated StackOverflow answers, showing how to solve each problem with .NET 2 or even older. Even worse, most examples lack key aspects like exception handling and bad practices. For today's post, I will show you the best ways of converting strings to integers in C#.

You have already tried converting a string to an int. Like parsing input from a text box in a system that didn't have modern model binding as we are used to today or when converting the output from a third-party API. While working for multiple companies both as a permanent and as a freelancer, I've seen a thousand lines of code, converting between data types. The most common pattern I've seen in C# is using the `Parse`-method:

```csharp
var i = int.Parse("42");
```

While `Parse` provides a nice and simple interface for converting strings to int, it's rarely the right method to use. What happens if you provide something else than a number to the `Parse`-method:

```csharp
var i = int.Parse("Oh no");
```

As expected, the `Parse`-method throws a `FormatException`. I cannot count the times I've seen this construct:

```csharp
string s = "...";
int i = 0;
try
{
    i = int.Parse(s);
}
catch (FormatException)
{
}
```

Even documentation shows this approach as a valid way to parse ints. So, why is this a poor solution? Using exceptions as a control flow reduces the performance and makes your code harder to read. Luckily, .NET provides a much better way to parse ints without the need to catch exceptions: the `TryParse`-method:

```csharp
string s = "...";
if (!int.TryParse(s, out int i))
{
    // Decide what to do since s cannot be parsed as an int
}

// Carry on
```

`TryParse` returns a boolean indicating if the parameter (`s`) was successfully parsed or not. If parsed, the value will go into the `out` parameter (`i`). Parsing with a default value on an invalid string is still dead simple:

```csharp
int i = 0;
int.TryParse(s, out i);
// i is 0 if s could not be parsed as an int
```

## Convert.ToInt32

There's a `Convert` class in the `System` namespace that you may be aquainted with. `Convert` offers a range of methods for converting one data type to another. For converting strings to ints, it's an abstraction on top of the `Parse` method from the previous section. This means that you will need to catch the `FormatException` to use the `ToInt32`-method:

```csharp
string s = "...";
int i = 0;
try
{
    i = Convert.ToInt32(s);
}
catch (FormatException)
{
}
```

While it might be nice with a common abstraction for converting data types, I tend not to use the `Convert` class. Being forced to control flow using exceptions is something I always try to avoid, which (to my knowledge) isn't possible with the `Convert` class. Besides this, there are some additional things that you will need to be aware of when using the `ToInt32`-method. Take a look at the following code:

```csharp
var i = Convert.ToInt32('1');
Console.WriteLine(i);
```

In the code, I'm converting the char `1` to an integer and writing it to the console. What do you expect the program to produce? The number `1`, right? That's not the case, though. The overload of the `ToInt32`-method accepting a `char` as a parameter, converts the `char` to its UTF code, in this case `49`. I've seen this go down a couple of times.

To summarize my opinion about the `Convert`-class in terms of converting strings to integers, stick to the `TryParse`-method instead.

## Exception handling

As long as you use the `TryParse`-method, there's no need to catch any exceptions. Both the `Parse` and the `ToInt32`-method requires you to deal with exceptions:

```csharp
try
{
    var result = int.Parse(s);
}
catch (ArgumentNullException)
{
    // s is null
}
catch (FormatException)
{
    // s is not a valid int
}
catch (OverflowException)
{
    // s is less than int.MinValue or more than int.MaxValue
}
```

## Parsing complex strings

From my time working with financial systems, I was made aware of an overload of the `TryParse`-method that I don't see a lot of people using. The overload looks like this:

```csharp
public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out Int32 result);
```

The parameter that I want to introduce you to is `NumberStyles` enum. The parameter accepts a bitwise combination of flags, allowing for more complex strings to be successfully parsed as integers. It's often much more readable to use this `TryParse`-overload, rather than doing a range of manipulations on the input string before parsing (like removing thousand separators, whitespaces, currency signs, etc.). Let's look at a couple of examples:

```csharp
int.TryParse("(42)", System.Globalization.NumberStyles.AllowParentheses, null, out int result);

// result is -42
```

`AllowParantheses` will accept parantheses in the input string. But be aware that a parenthesized string is converted to a negative value. This format is often used in accounting and financial systems.

```csharp
int.TryParse("$42", System.Globalization.NumberStyles.AllowCurrencySymbol, null, out int result);

// Result is 42
```

`AllowCurrencySymbol` will accept currency symbols inside the input string.

```csharp
int.TryParse("42,000", System.Globalization.NumberStyles.AllowThousands, null, out int result);

// Result is 42000
```

`AllowThousands` will accept a thousand separator in the input string.

Like any bitwise flag, multiple `NumberStyles` can be combined:

```csharp
int.TryParse(
    "($42,000)",
    System.Globalization.NumberStyles.AllowThousands |
    System.Globalization.NumberStyles.AllowParentheses |
    System.Globalization.NumberStyles.AllowCurrencySymbol,
    null,
    out int result);

// Result is -42000
```

## Parsing anti-patterns

When looking at code, I often see different anti-patterns implemented around int parsing. Maybe someone copies code snippets from Stack Overflow or blog posts with unnecessary code, who knows. This section is my attempt to debunk common myths.

### Trimming for whitespace

This is probably the most common code example I've seen:

```csharp
int.TryParse(" 42".Trim(), out int result);
```

By calling `Trim` the developer makes sure not to parse a string with whitespaces in the start and/or end. Trimming strings isn't nessecary, though. The `TryParse`-method automatically trims the input string.

### Not using the `TryParse` overload

Another common anti-pattern is to do manual string manipulation to a string before sending it to the `TryParse`-method. Examples I've seen is to remove thousand separators, currency symbols, etc.:

```csharp
int.TryParse("42,000".Replace(",", ""), out int result);
```

Like we've already seen, calling the `TryParse`-overload with the `AllowThousands` flag (or one of the others depending in the input string) is a better and more readable solution.

### Control flow with exceptions

We already discussed this. But since this is a section of anti-patterns I want to repeat it. Control flow with exceptions slow down your code and make it less readable:

```csharp
int result;
try
{
    result = int.Parse(s);
}
catch (FormatException)
{
    result = 42;
}
```

As I already mentioned, using the TryParse-method is a better solution here.

### Avoid out parameters

There's a bit of a predicament when using the `TryParse`-method. Static code analysis tools often advise against using `out` parameters. I don't disagree there. `out` parameters allows for returning multiple values from a method which can violate the single responsibility principle. Whether you want to use the `TryParse`-method probably depends on how strict you want to be concerning the single responsibility principle.

If you want to, you can avoid the out parameter (or at least only use it once) by creating a small extension method:

```csharp
public static class StringExtensions
{
    public static (int result, bool canParse) TryParse(this string s)
    {
        int res;
        var valid = int.TryParse(s, out res);
        return (result: res, canParse: valid);
    }
}
```

The method uses the built-in tuple support available in C# 7.

### Convert to an array

A question that I often see is the option of parsing a list of integers in a string and converting it to an array or list of integers. With the knowledge already gained from this post, converting a `string` to an `int` array can be done easily with a bit of LINQ:

```csharp
var s = "123";
var array = s
    .Split()
    .Select(s => Convert.ToInt32(s))
    .ToArray();
```

By splitting without parameters we get an enumerable of individual characters that can be converted to integers.

In most cases you would get a comma-separated list or similar. Parsing and converting that will require some arguments for the `Split` method:

```csharp
var s = "1,2,3";
var array = s
    .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
    .Select(s => Convert.ToInt32(s))
    .ToArray();
```

By splitting the string on comma (`,`) we get the individual characters in between.

When working with external APIs, developers come up with all sorts of weird constructs for representing null or other non-integer values. To make sure that you only parse integers, use the `Char.IsNumber` helper:

```csharp
var s = "1,2,null,3";
var array = s
    .ToCharArray()
    .Where(c => Char.IsNumber(c))
    .Select(c => Convert.ToInt32(c.ToString()))
    .ToArray();
```

By only including characters which are numbers, we filter values like `null` from the input string.

## Would your users appreciate fewer errors?

elmah.io is the easy error logging and uptime monitoring service for .NET. Take back control of your errors with support for all .NET web and logging frameworks.

➡️ [Error Monitoring for .NET Web Applications](https://elmah.io/?utm_source=devto&utm_medium=social&utm_campaign=devtoposts) ⬅️

This article first appeared on the elmah.io blog at https://blog.elmah.io/csharp-how-to-convert-a-string-to-int/