Convert.ToBoolean fails with "0" value

This is happening because Convert.ToBoolean is expecting one of the following:

  • "True" (String) = true
  • "False" (String) = false
  • 0 (numerical type; int, double, float, etc.) = false
  • Any non-0 (numerical type; ...) = true
  • null = false

Any other value is invalid for Boolean.

You've already got a clean approach:

var myValue = Convert.ToBoolean(Convert.ToInt32("0"));

Edit: You can create an extension method that will handle a few of these cases for you, while hiding away the ugliness of handling the conversion.

This extension provides a very loose interpretation of Boolean:

  • "True" (String) = true
  • "False" (String) = false
  • "0" (String) = false
  • Any other string = true

Code:

public static class Extensions
{
    public static Boolean ToBoolean(this string str)
    {
        String cleanValue = (str ?? "").Trim();
        if (String.Equals(cleanValue, "False", StringComparison.OrdinalIgnoreCase))
            return false;
        return
            (String.Equals(cleanValue, "True", StringComparison.OrdinalIgnoreCase)) ||
            (cleanValue != "0");
    }
}

Alternatively, if you want a more strict approach, which follows what the .NET Framework expects; then simply use try/catch statements:

public static class Extensions
{
    public static Boolean ToBoolean(this string str)
    {
        try
        {
            return Convert.ToBoolean(str);
        }
        catch { }
        try
        {
            return Convert.ToBoolean(Convert.ToInt32(str));
        }
        catch { }
        return false;
    }
}

Albeit, not a clean or pretty approach, but it guarantees more possibilities of getting the correct value. And, the Extensions class is tucked away from your data/business code.

In the end, your conversion code is relatively simple to use:

String myString = "1";
Boolean myBoolean = myString.ToBoolean();

public static class BooleanParser
{
    public static bool SafeParse(string value)
    {
        var s = (value ?? "").Trim().ToLower();
        return s == "true" || s == "1";
    }
}

static readonly HashSet<string> _booleanTrueStrings = new HashSet<string> { "true", "yes", "1" };
static readonly HashSet<string> _booleanFalseStrings = new HashSet<string> { "false", "no", "0" };

public static bool ToBoolean(string value)
{
    var v = value?.ToLower()?.Trim() ?? "";
    if (_booleanTrueStrings.Contains(v)) return true;
    if (_booleanFalseStrings.Contains(v)) return false;
    throw new ArgumentException("Unexpected Boolean Format");
}

Since it's really a matter of still doing those conversions and such, how about an extension method?

public static class Extensions {
    public static bool ToBool(this string s) {
        return s == "0" ? false : true;
    }
}

and so then you would use it like this:

"0".ToBool();

and now you could easily extend this method to handle even more cases if you wanted.