Domanda

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?
È stato utile?

Soluzione

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();

Altri suggerimenti

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.

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.

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);
}

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; }
        }
}

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;
    }
}
    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

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

return (string!= "0")

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top