C# programming
Boolean conversion
Convert.ToBoolean
Boolean.Parse
.NET framework

Convert.ToBoolean and Boolean.Parse don't accept 0 and 1

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In .NET, boolean parsing depends on both the input type and the API overload you call. Many developers expect the strings 0 and 1 to behave like numeric booleans, but bool.Parse and the string overload of Convert.ToBoolean only recognize textual True and False. The confusion usually comes from mixing string data with numeric conversion rules.

String Parsing Rules Are Strict

If the input is a string, both bool.Parse and bool.TryParse follow the same textual model. They accept case-insensitive forms of True and False, plus surrounding whitespace.

csharp
1using System;
2
3Console.WriteLine(bool.Parse("true"));
4Console.WriteLine(bool.Parse(" False "));
5
6Console.WriteLine(bool.TryParse("TRUE", out var a));
7Console.WriteLine(a);

But numeric strings are not valid boolean text:

csharp
1using System;
2
3Console.WriteLine(bool.TryParse("1", out var value)); // False
4
5try
6{
7    Console.WriteLine(bool.Parse("0"));
8}
9catch (FormatException ex)
10{
11    Console.WriteLine(ex.GetType().Name);
12}

If your source value is text, the parser treats it as text, not as an integer that happens to be written with digits.

Numeric Conversion Follows Different Rules

The Convert.ToBoolean overloads for numeric types do accept numbers. Zero becomes false, and any non-zero numeric value becomes true.

csharp
1using System;
2
3Console.WriteLine(Convert.ToBoolean(0));   // False
4Console.WriteLine(Convert.ToBoolean(1));   // True
5Console.WriteLine(Convert.ToBoolean(42));  // True
6Console.WriteLine(Convert.ToBoolean(-7));  // True

That behavior is valid for numeric input, but it does not apply when the source is the string "1".

Build One Parser for Mixed Legacy Input

If you have to support a legacy format that may contain true, false, 0, or 1, write one small parsing function and use it everywhere.

csharp
1using System;
2
3public static class LooseBoolean
4{
5    public static bool TryParse(string? input, out bool result)
6    {
7        result = false;
8
9        if (input is null)
10        {
11            return false;
12        }
13
14        var value = input.Trim();
15
16        if (string.Equals(value, "true", StringComparison.OrdinalIgnoreCase) || value == "1")
17        {
18            result = true;
19            return true;
20        }
21
22        if (string.Equals(value, "false", StringComparison.OrdinalIgnoreCase) || value == "0")
23        {
24            result = false;
25            return true;
26        }
27
28        return false;
29    }
30}

This keeps parsing policy centralized. Otherwise, one API endpoint may accept "1" while another rejects it, which is difficult to debug.

Prefer Canonical Types at the Boundary

If you control the payload format, do not send booleans as strings in the first place. JSON should use real booleans, database columns should use an intentional boolean or numeric type, and internal domain objects should hold bool, not "true" or "0".

csharp
1public sealed class FeatureFlagRequest
2{
3    public bool Enabled { get; init; }
4}

Once the value is normalized to bool near the boundary, the rest of the code becomes simpler and safer.

Validate Source Type Before Converting

When the source is an object, inspect the actual type first instead of guessing.

csharp
1using System;
2
3object raw = "1";
4
5bool parsed = raw switch
6{
7    bool b => b,
8    int i => Convert.ToBoolean(i),
9    string s when LooseBoolean.TryParse(s, out var value) => value,
10    _ => throw new FormatException("Unsupported boolean value"),
11};
12
13Console.WriteLine(parsed);

This approach makes the conversion rules explicit and easier to review.

Common Pitfalls

The most common pitfall is assuming that "1" and 1 are interchangeable. They are not, because the parser path depends on type.

Another mistake is throwing parsing logic all over the codebase instead of defining one accepted input policy. Once different services interpret the same value differently, bugs become hard to trace.

It is also common to use Parse where TryParse would be better. Exception-driven control flow is noisy for user input and import pipelines.

Finally, if you control the contract, avoid string booleans entirely. The cleanest fix is often a better schema.

Summary

  • 'bool.Parse and bool.TryParse accept textual True and False, not numeric strings.'
  • Numeric overloads of Convert.ToBoolean do convert 0 and non-zero numbers.
  • The difference comes from the input type, not from random parser inconsistency.
  • Centralize mixed-format parsing when legacy data forces you to accept both styles.
  • Prefer real boolean types at system boundaries whenever you control the contract.

Course illustration
Course illustration

All Rights Reserved.