2013-04-25 3 views
16

Я пытаюсь преобразовать значение "0" (System.String) его Boolean представления, как:Convert.ToBoolean терпит неудачу со значением «0»

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

Я смотрел на MSDN page, а в коде -sample блок, я нашел эти строки:

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

в моем коде, я преобразование из System.String в Boolean так:

// will be OK, but ugly code 
var myValue = Convert.ToBoolean(Convert.ToInt32("0")); 
  • Есть ли способ конвертировать в Boolean тип с не таким уродливым кодом?
  • Почему возникает такое исключение? Из-за преобразования из ссылочного типа System.String в тип значения System.Boolean, но System.Int32 также является типом значений, не так ли?
+1

Пример вы ссылаетесь показывает, что есть недействительные строки, метод ToBoolean() отклонит. В дополнение к «0», они показывают примеры «TrueString» и string.Empty. Образец показывает, что они недействительны, а не то, что вы действительно можете использовать эти значения. –

+0

Почему бы не использовать var res = "1yestrue". Содержит (вашVar)? Есть также Boolean.Parse()/Boolean.TryParse()? – Bernhard

ответ

47

Это происходит потому, что Convert.ToBoolean ожидает одно из следующих действий:

  • "True" (String) = true
  • "False" (String) = false
  • 0 (числовой тип; INT, двойная, с плавающей точкой, и т.д.) = false
  • Любые не 0 (числовой тип; ...) = true
  • null = false

Любая другая значение является недопустимым для Boolean.

Вы уже получили чистый подход:

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

Edit: Вы можете создать метод расширения, который будет обрабатывать некоторые из этих случаев для вас, скрывая прочь уродство обращения с конверсией.

Это расширение обеспечивает очень свободную интерпретацию Boolean:

  • "True" (String) = true
  • "False" (String) = false
  • "0" (String) = false
  • Любая другая строка = true

Код:

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

В качестве альтернативы, если вы хотите более строгий подход, который следует, что ожидает .NET Framework; затем просто использовать 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; 
    } 
} 

Albeit, не чистый или довольно подход, но это гарантирует больше возможностей получения правильного значения. И класс Extensions спрятан от вашего кода данных/бизнеса.

В конце концов, ваш код преобразования относительно прост в использовании:

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

попытайтесь преобразовать в логический тип «0», как я сказал в теме, и посмотрите пример msdn: http://msdn.microsoft.com/en-us/library/86hw82a3.aspx, вы получите excpetion с попыткой преобразования строкового значения «0». – Secret

+0

Поскольку '' 0 "' is * not * '" True "или' False "'. Представленное ** ** ** представление строки является «True» или «False». – Jesse

+0

вы обновили ответ: первый вариант был другим и удерживал «0» в списке, поэтому мой комментарий ссылался на него, а не на обновленный :) и самый чистый подход выглядит уродливым для стиля кода – Secret

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

Поскольку это действительно вопрос до сих пор делают эти преобразования и такие, как насчет метода расширения?

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

и так, то вы бы использовать его как это:

"0".ToBool(); 

и теперь вы можете легко расширить этот метод для обработки даже больше случаев, если вы хотите.

1

Для успешного преобразования произойдет, то значение параметр должен быть равен либо Boolean.TrueString, константа, значение которого True, Boolean.FalseString, константа, значение которого False, или он должен быть нулевым. При сравнении значения с Boolean.TrueString и Boolean.FalseString, метод игнорирует регистр, а также пробел в начале и конце.

MSDN от

, потому что Convert.ToBoolean ожидает true if value is not zero; otherwise, false. численного значения и True или FalseString значения.

1

Если вы знаете, что это будет int, вы можете преобразовать его в int, а затем в bool. Следующее попытается выполнить преобразование в bool, попытавшись создать строку, а затем попытаться с номером.

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

Вот очень снисходителен анализатор, что ключи прочь от первого символа:

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

достаточно быстро и просто:

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; } 
     } 
} 
Смежные вопросы