Better way of parsing string to boolean

  • At the moment I am using this to check a boolean property in sharepoint 2007 using C# and .Net Framework 3.5



    if (bool.Parse(listItem.Properties["Boolean Property"].ToString()) == false)


    is there any better way of doing it ?



    Edit



    when my code try to convert property into string it gives me exception even when am validating if property is empty or not.



    This Worked For me



    using method "Contains Key" instead of "Properties.Containsfield"



    object abc = "bool property";

    foreach (SPListItem item in list.Items)
    {
    if (item.Properties.ContainsKey(abc)

    I explained some of the errors that your approach is likely to generate in my answer. My guess is it's either a `NullReferenceException` or a `FormatException`

    Unrelated, but note that use of boolean literals in comparisons is something that I’d flag in every code review. Boolean literals have one use, and one use only: to initialise a boolean value.

  • I am making some assumptions about your code, specifically that listItem is of type SPListItem and that listItem.Properties is a HashTable. This is mainly to provide context for my explanation, but even if I am mistaken, most of my comments will still hold. For the sake of context, let's assume your actual method looks like:



     void HandleBooleanListItemProperty( SPListItem listItem ){ 
    if (bool.Parse(listItem.Properties["Boolean Property"].ToString()) == false){
    // do something if the Boolean ListItem property is false
    }
    else
    {
    // do something if the Boolean ListItem property is true
    }
    }



    1. Validate that the object exists before you call ToString(). The way your method is currently written, you will get a NullReferenceException if the key "Boolean Property" is missing or the hashed value that corresponds to the "Boolean Property" key is null. This refactoring will make the method look like:



      void HandleBooleanListItemProperty2( SPListItem listItem ){ 
      object booleanPropertyValue = listItem.Properties["Boolean Property"];
      if ( ReferenceEquals( booleanPropertyValue, null ) ) {
      // do something if the Boolean ListItem property is missing
      }
      else if (bool.Parse(booleanPropertyValue.ToString()) == false){
      // do something if the Boolean ListItem property is false
      }
      else {
      // do something if the Boolean ListItem property is true
      }
      }

    2. Use bool.TryParse instead of bool.Parse. If the ToString() value of the hashed value corresponding to the key "Boolean Property" is anything other than "true" or "false" (case-insensitive), a FormatException will be thrown. This refactoring will make the method look like:



       void HandleBooleanListItemProperty3( SPListItem listItem ){ 
      object booleanPropertyValue = listItem.Properties["Boolean Property"];
      bool parsedBooleanPropertyValue;
      if ( ReferenceEquals( booleanPropertyValue, null ) ) {
      // do something if the Boolean ListItem property is missing
      }
      else if (bool.TryParse(booleanPropertyValue.ToString(), out parsedBooleanPropertyValue) )
      {
      if(parsedBooleanPropertyValue == false){
      // do something if the Boolean ListItem property is false
      }
      else {
      // do something if the Boolean ListItem property is true
      }
      }
      else {
      // do something if the Boolean ListItem property's ToString() value was something other than "true" or "false"
      }
      }

    3. If the hashed value that corresponds to the "Boolean Property" key is really a bool, then cast it before comparing. Calling ToString() just throws away .NET's type-safety. This refactoring will make the method look like:



       void HandleBooleanListItemProperty4( SPListItem listItem ){ 
      object booleanPropertyValue = listItem.Properties["Boolean Property"];
      if (booleanPropertyValue is bool)
      {
      bool castBooleanPropertyValue = (bool) booleanPropertyValue;
      if( castBooleanPropertyValue == false ){
      // do something if the Boolean ListItem property is false
      }
      else {
      // do something if the Boolean ListItem property is true
      }
      }
      else {
      // do something if the Boolean ListItem property is not a bool
      if ( ReferenceEquals( booleanPropertyValue, null ) ) {
      // do something if the Boolean ListItem property is missing
      }
      else {
      // do something if the Boolean ListItem property is something other than a bool
      }
      }
      }

    4. Eliminate magic strings from your value accessor. This requires removing the inline "Boolean Property" and declaring with that value, and then using the constant in order to access the value in every usage. This decreases the possibility that a typos will cause bugs. An article on magic strings is available at: http://codebetter.com/matthewpodwysocki/2009/03/19/functional-net-lose-the-magic-strings/ . The resulting refactoring would look like:



       const string BooleanPropertyKey = "Boolean Property";

      void HandleBooleanListItemProperty5( SPListItem listItem ){
      object booleanPropertyValue = listItem.Properties[BooleanPropertyKey];
      if (booleanPropertyValue is bool)
      {
      bool castBooleanPropertyValue = (bool) booleanPropertyValue;
      if( castBooleanPropertyValue == false ){
      // do something if the Boolean ListItem property is false
      }
      else {
      // do something if the Boolean ListItem property is true
      }
      }
      else {
      // do something if the Boolean ListItem property is not a bool
      if ( ReferenceEquals( booleanPropertyValue, null ) ) {
      // do something if the Boolean ListItem property is missing
      }
      else {
      // do something if the Boolean ListItem property is something other than a bool
      }
      }
      }

    5. Use the negation operator (!) instead of comparing to false. This is much more readable and will save you time in the long run. This final refactoring looks like:



       const string BooleanPropertyKey = "Boolean Property";

      void HandleBooleanListItemProperty6( SPListItem listItem ){
      object booleanPropertyValue = listItem.Properties[BooleanPropertyKey];
      if (booleanPropertyValue is bool)
      {
      bool castBooleanPropertyValue = (bool) booleanPropertyValue;
      if( !castBooleanPropertyValue ){
      // do something if the Boolean ListItem property is false
      }
      else {
      // do something if the Boolean ListItem property is true
      }
      }
      else {
      // do something if the Boolean ListItem property is not a bool
      if ( ReferenceEquals( booleanPropertyValue, null ) ) {
      // do something if the Boolean ListItem property is missing
      }
      else {
      // do something if the Boolean ListItem property is something other than a bool
      }
      }
      }


    thanks for explaining it in details and I did tried number 5, but when property is there it isn't going to first if statement but going to else statement and I just debugged and looked at what property is returned as and its returned as "1" for that particular item and code thinks its not boolean

    @TimeToThine, I guess you are used to working with JavaScript, huh? In C#, `1` is not a `Boolean`. It is an integer. You can use the same approach with `int` instead of `bool`, and then check `if( ((int)listItem.Properties[BooleanPropertyKey]) == 1 )`

    sorry am bit confused now, I looked at XML returned by SharePoint in my solution while its attached to list and in XML it got "1" as value for that property but when I tried to get values of all items using console app, its giving me as true, however for one item I am getting "object not set to reference" for which I think has been already added before custom property wasn't added to list.

    XML stores a boolean value as a `1`. This is different than the C# literal `1`. If you are deserializing the XML document to a `HashTable`, it should be converted to a `Boolean`. Your problem is that there is no value in the `HashTable` with the key "Boolean Property", so when you ask the `HashTable` for it, it gives you `null`. When you ask `null` for `ToString()`, it gives you a `NullReferenceException` ("Object not set to a reference")

    thats true, I think I want to catch this this null exception in a way that I can do something with it without throwing any exception, just like you explained it in code above, but number 5 isn't working like it should be :(

    @TimeToThine, I guarantee you the code will "work like it should". Maybe you are not realizing that a null reference will not be seen as a `bool`. So, for example, if there is no "Boolean Property" attribute in the XML element, then there will be no reference in the `HashTable`, and so it will throw an error.

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM

Tags used