Convert.ToBoolean fails with "0" value
Asked Answered
R

9

27

I'm trying to convert the value "0" ( System.String ) to its Boolean representation, like:

var myValue = Convert.ToBoolean("0"); // throwing an exception here

I've looked at the MSDN page, and in the code-sample block, I found these lines:

ConvertToBoolean("0");
// ...
Unable to convert '0' to a Boolean.

In my code, I'm converting from the System.String to Boolean like this:

// will be OK, but ugly code
var myValue = Convert.ToBoolean(Convert.ToInt32("0"));
  • Is there any other way to convert to the Boolean type with not such ugly code?
  • Why does such an exception occur? Because of converting from the reference type System.String to the value type the System.Boolean, but System.Int32 is also a value type, isn't it?
Raposa answered 25/4, 2013 at 2:30 Comment(3)
The example you reference is showing that there are invalid strings that the ToBoolean() method will reject. In addition to "0", they show examples of "TrueString" and string.Empty. The sample is showing that these are invalid, not that you can actually use those values.Hyponasty
why not use var res="1yestrue".Contains(yourVar)? There are also Boolean.Parse() / Boolean.TryParse() ?Sarcasm
simply use Convert.ToInt32("0") > 0 which gives you bool .Sulphanilamide
D
71

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

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();
Dareen answered 25/4, 2013 at 2:33 Comment(6)
try to convert to the Boolean type the "0" as I said in the topic and look at the msdn sample on: msdn.microsoft.com/en-us/library/86hw82a3.aspx, you will get an excpetion with a try of converting the "0" string value.Raposa
Because "0" is not "True" or "False". The only string representation accepted is "True" or "False".Dareen
you have refreshed you answer :) first variant of it was different and hold the "0" in the list, so my comment was referenced to it, not the refreshed one :) also the cleanest approach does look ugly for code-styleRaposa
You can use extension method to have the Parse Boolean as you wish. It will make your code clean and straight forward into convert boolean from string.Knitted
@ToanVo Thanks for the tip; I've added some sample Extensions methods.Dareen
@Dareen thank you too for the great answer ;) I think, that such a question will be a good exercise for the students or a good test for the job interview. Just to make a Q in the test about such a problem and ask about solutions or possible exceptions.Raposa
C
7
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");
}
Chapin answered 25/4, 2013 at 2:34 Comment(0)
L
3

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.

Lunseth answered 25/4, 2013 at 2:37 Comment(0)
G
1

For a successful conversion to occur, the value parameter must equal either Boolean.TrueString, a constant whose value is True, Boolean.FalseString, a constant whose value is False, or it must be null. In comparing value with Boolean.TrueString and Boolean.FalseString, the method ignores case as well as leading and trailing white space.

from MSDN

because Convert.ToBoolean expects a true if value is not zero; otherwise, false. numerical value and True or False String value.

Glynda answered 25/4, 2013 at 2:37 Comment(0)
L
1

If you know that it would be an int then you can convert it to int then to bool. Following will try for conversion to bool by attempting the string then attempting with number.

public bool ToBoolean(string value)
{
  var boolValue = false;
  if (bool.TryParse(value, out boolValue ))
  {
    return boolValue;
  }

  var number = 0;
  int.TryParse(value, out number))
  return Convert.ToBoolean(number);
}
Laryngoscope answered 25/4, 2013 at 2:40 Comment(0)
G
1

Fast enough and simple:

public static class Extensions
{
        static private List<string> trueSet = new List<string> { "true","1","yes","y" };

        public static Boolean ToBoolean(this string str)
        {
            try
            { return trueSet.Contains(str.ToLower()); }
            catch { return false; }
        }
}
Gennygeno answered 21/6, 2017 at 10:1 Comment(0)
A
0

Here's a very forgiving parser that keys off of the first character:

public static class StringHelpers
{
    /// <summary>
    /// Convert string to boolean, in a forgiving way.
    /// </summary>
    /// <param name="stringVal">String that should either be "True", "False", "Yes", "No", "T", "F", "Y", "N", "1", "0"</param>
    /// <returns>If the trimmed string is any of the legal values that can be construed as "true", it returns true; False otherwise;</returns>
    public static bool ToBoolFuzzy(this string stringVal)
    {
        string normalizedString = (stringVal?.Trim() ?? "false").ToLowerInvariant();
        bool result = (normalizedString.StartsWith("y") 
            || normalizedString.StartsWith("t")
            || normalizedString.StartsWith("1"));
        return result;
    }
}
Acidforming answered 3/11, 2015 at 18:14 Comment(0)
P
0
    public static bool GetBoolValue(string featureKeyValue)
    {
        if (!string.IsNullOrEmpty(featureKeyValue))
        {
                    try 
                    {
                        bool value;
                        if (bool.TryParse(featureKeyValue, out value))
                        {
                            return value;
                        }
                        else
                        {
                            return Convert.ToBoolean(Convert.ToInt32(featureKeyValue));
                        }
                    }
                    catch
                    {
                        return false;
                    }
         }
         else
         {
                  return false;
         }
   }

You can call it like following -:

GetBoolValue("TRUE") // true
GetBoolValue("1") // true
GetBoolValue("") // false
GetBoolValue(null) // false
GetBoolValue("randomString") // false
Potency answered 18/3, 2019 at 10:37 Comment(0)
V
0

its too late but if someone other is looking for same , can try this its short and easy

return (string!= "0")

Verrocchio answered 18/7, 2021 at 10:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.