J'essaie de convertir la valeur "0"
(System.String
) en sa représentation Boolean
, telle que:
var myValue = Convert.ToBoolean("0"); // throwing an exception here
J'ai consulté la page MSDN , et dans le bloc exemple de code, j'ai trouvé les lignes suivantes:
ConvertToBoolean("0");
// ...
Unable to convert '0' to a Boolean.
Dans mon code, je convertis du System.String
en Boolean
comme ceci:
// will be OK, but ugly code
var myValue = Convert.ToBoolean(Convert.ToInt32("0"));
Boolean
avec un code si peu laid?System.String
en valeur, le System.Boolean
, mais System.Int32
est également un type de valeur, n'est-ce pas?Cela se produit parce que Convert.ToBoolean
attend l'un des éléments suivants:
"True"
(Chaîne) = true
"False"
(Chaîne) = false
0
(type numérique; int, double, float, etc.) = false
0
(type numérique; ...) = true
null
= false
Toute valeur autre n'est pas valide pour Boolean
.
Vous avez déjà une approche propre:
var myValue = Convert.ToBoolean(Convert.ToInt32("0"));
Edit: Vous pouvez créer une méthode d'extension qui gérera quelques-uns de ces cas pour vous, tout en cachant la laideur du traitement de la conversion.
Cette extension fournit une interprétation très vague de Boolean
:
"True"
(String) = true
"False"
(String) = false
"0"
(String) = false
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");
}
}
Sinon, si vous souhaitez une approche plus stricte, qui suit les attentes du .NET Framework; puis utilisez simplement les instructions try/catch
:
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;
}
}
Bien que ce ne soit pas une approche propre ou jolie, elle garantit davantage de possibilités d'obtenir la valeur correcte. Et la classe Extensions
est cachée de votre code de données/métier.
Au final, votre code de conversion est relativement simple à utiliser:
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");
}
Puisqu'il s'agit vraiment de continuer à faire ces conversions, pourquoi ne pas utiliser une méthode d'extension?
public static class Extensions {
public static bool ToBool(this string s) {
return s == "0" ? false : true;
}
}
et alors vous l'utiliseriez comme ceci:
"0".ToBool();
et maintenant, vous pouvez facilement étendre cette méthode pour traiter encore plus de cas si vous le souhaitez.
Assez rapide et 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; }
}
}
Pour qu'une conversion réussisse, le paramètre value doit être égal à Boolean.TrueString
, une constante dont la valeur est True
, Boolean.FalseString
, une constante dont la valeur est False
ou doit être null. En comparant la valeur avec Boolean.TrueString et Boolean.FalseString, la méthode ignore la casse ainsi que les espaces blancs de début et de fin.
depuis MSDN
parce que Convert.ToBoolean
attend un vrai si la valeur n'est pas zéro; sinon, faux. valeur numérique et True
ou False
String
valeur.
Si vous savez que ce serait un int, vous pouvez le convertir en int puis en bool. La suite va essayer de convertir en bool en essayant la chaîne puis en essayant un nombre.
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);
}
Voici un analyseur très pardonnant qui supprime le premier caractère:
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;
}
}