Convert.ToBoolean and Boolean.Parse don't accept 0 and 1
Why was it decided that when parsing a boolean, 0/1 are not acceptable?
When parsing any integer type value, it accepts numerical strings to be parsed. (And if .NET can parse the string "One hundred million two hundred and sixty five thousand eight 开发者_运维知识库hundred and sixty five" I would be surprised).
What makes booleans special? They are essentially 0 as false, and non-zero as true in my experience...
Is there a bcl method to parse a string like this, and if not, why?
Note: I forgot to specify in a string "0" and "1". Curious though that if already an int it works as I anticipated. Maybe this caused the confusion.
0 and (not-zero) are not equal to "false" and "true", they're just the representation chosen by C. Other languages use 0 for true and -1 for false, or other schemes entirely. A boolean is not a 0 or a 1, it's a true or a false.
Should it also handle "yes" and "no", "off" and "on", and all of the myriad other things that are analogous to booleans? Where would you draw the line?
What makes booleans special? They are essentially 0 as false, and non-zero as true in my experience...
That is an implementation detail, and isn't at all relevant.
true
is a boolean value. false
is a boolean value. Anything else is not.
If you want to parse something such that the string "0" evaluates false
while anything else evaluates true
, you can use:
!mystr.Equals("0");
The shared FormatHelper
class shown below provides a simple solution using two variations of an overloaded method called StringToBoolean
.
FormatHelper.StringToBoolean(String value)
FormatHelper.StringToBoolean(String value, Boolean NullOrEmptyDefault)
Both variations provide a case-insentive string match
1) The normal convertion from string to boolean defaulting empty or null strings to false
The following examples will result in a boolean
value of false
:-
Boolean myBool = FormatHelper.StringToBoolean("");
Boolean myBool = FormatHelper.StringToBoolean("0");
Boolean myBool = FormatHelper.StringToBoolean("false");
Boolean myBool = FormatHelper.StringToBoolean("False");
Boolean myBool = FormatHelper.StringToBoolean("no");
Boolean myBool = FormatHelper.StringToBoolean("off");
All other string values will result in a Boolean
value of true
such as:-
Boolean myBool = FormatHelper.StringToBoolean("1");
Boolean myBool = FormatHelper.StringToBoolean("true");
Boolean myBool = FormatHelper.StringToBoolean("True");
Boolean myBool = FormatHelper.StringToBoolean("yes");
Boolean myBool = FormatHelper.StringToBoolean("xyz blah");
Note: Edit the value of BooleanStringOff
in the class below to include more (or less) values for false/off
2) Follows the same rules as 1) above but allows a default value of true
to be supplied as the 2nd argument to the conversion.
The default value is used when the String
value is empty or null
. This is useful if a missing string value needs to signify a true
state.
The following code example will return true
Boolean myBool = FormatHelper.StringToBoolean("",true);
The following code example will return false
Boolean myBool = FormatHelper.StringToBoolean("false",true);
This is the code for the FormatHelper
class
public class FormatHelper
{
public static Boolean StringToBoolean(String str)
{
return StringToBoolean(str, false);
}
public static Boolean StringToBoolean(String str, Boolean bDefault)
{
String[] BooleanStringOff = { "0", "off", "no" };
if (String.IsNullOrEmpty(str))
return bDefault;
else if(BooleanStringOff.Contains(str,StringComparer.InvariantCultureIgnoreCase))
return false;
Boolean result;
if (!Boolean.TryParse(str, out result))
result = true;
return result;
}
}
Unfortunately, this happens a lot in .NET. For example, I can't remember if it's XML Serializer or XmlConvert but one of them fails if the casing of True/False are not correct.
You can round trip through integer to get what you want.
string s = "2";
int i = Convert.ToInt32(s);
bool b = Convert.ToBoolean(i);
In the above case, anything non-zero will evaluate to true.
For this reason, I created a class I use all over called ConversionStrategy which takes into account the source type and destination type and chooses the most ideal (and flexible) conversion strategy for making the conversion.
You want Convert.ToBoolean(int value)
not sure what's up with the Parse methods :-)
Code for no useful purpose:
int falseInt = 0;
int trueInt = 1;
bool falseBool;
bool trueBool;
if (bool.TryParse(falseInt.ToString(), out falseBool))
{
if (!falseBool)
{
MessageBox.Show("TryParse: False");
}
}
if (bool.TryParse(trueInt.ToString(), out trueBool))
{
if (!trueBool)
{
MessageBox.Show("TryParse: True");
}
}
falseBool = Convert.ToBoolean(falseInt);
trueBool = Convert.ToBoolean(trueInt);
if (!falseBool)
{
MessageBox.Show("Convert: False");
}
if (trueBool)
{
MessageBox.Show("Convert: True");
}
How about this?
byte i = 1; //or 0
bool myBool = BitConverter.ToBoolean(new byte[] { i }, 0)
To answer the question would be hard. Maybe because the narrow minded developers at Microsoft had their own reasons? No disrespect intended to them. Just saying they did not think about what it would need to be used for or how it would be used. I can't think of a reason why my extension below would not work for anyone. I mean a Boolean value is either on or off, true or false. In my mind it's basically binary. Parse methods for Int, Double, Char, Long, Byte, etc are more forgiving with their Parse methods.
However, consider this; You are looking to see if a value exists in an object. The same might be said for the following...
string myvar = "empty"; //Or maybe = "NULL"
if (String.IsNullOrEmpty(myvar))
{
//Should this be true?
}
Anyway, let's just make this simple. Here is my solution using an extension method to create a ToBoolean()
method for a string.
using System.Linq;
public static bool ToBoolean(this string input)
{
//Define the false keywords
String[] bFalse = { "false", "0", "off", "no" };
//Return false for any of the false keywords or an empty/null value
if (String.IsNullOrEmpty(input) || bFalse.Contains(input.ToLower()))
return false;
//Return true for anything not false
return true;
}
精彩评论