-1

I get the error "String was not recognized as a valid boolean" I am coding in C# and can't seems to find out what the problem is. Any insight would be very much appreciated. This is my code where it's failing:

    public static SalesInfo Parse(string stringValue)
    {
        string[] words;
        SalesInfo salesInfo = new SalesInfo();

        words = StringMethods.ParseCsvString(stringValue.Trim());
        salesInfo.ID = int.Parse(words[0]);
        salesInfo.Name = words[1];
        salesInfo.City = words[2];
        salesInfo.Senior = bool.Parse(words[3]);<----Error here
        salesInfo.Veteran = bool.Parse(words[4]);
        salesInfo.PurDate = Date.Parse(words[5]);
        salesInfo.ItemPrice = Double.Parse(words[6]);
        salesInfo.Quantity = int.Parse(words[7]);

        return salesInfo;
    }
walkerofskies1
  • 33
  • 1
  • 1
  • 4

2 Answers2

6

bool.Parse will only parse a string of "True" or "False" (case-insensitive).

The MSDN documentation for bool.TryParse shows a good example of the types of strings that can be parsed.

If your input string is some other variation of "truthiness" you would have to write your own parser. Something like:

public static SalesInfo Parse(string stringValue)
{
    ...cut for brevity...

    salesInfo.Senior = ParseBool(words[3]);

    return salesInfo;
}

public bool ParseBool(string input)
{
    switch (input.ToLower())
    {
        case "y":
        case "yes":
            return true;
        default:
            return false;
    }
}
Steve
  • 9,335
  • 10
  • 49
  • 81
  • @Igor I was really just demonstrating the concept, but sure. – Steve Oct 13 '16 at 01:38
  • I like this approach, I upvoted. One thing you could add too (in case the CSV file has "bad" data) is to add a separate case for "n", "no", etc. and have the default case throw an exception indicating that the data's bad. – EJoshuaS - Stand with Ukraine Oct 13 '16 at 01:45
  • 1
    @EJoshuaS yea, you would definately want to review the data to cover all "normal" bases and decide what you want the default outcome to be, either `false` or something like an `ArgumentException`. – Steve Oct 13 '16 at 01:57
1

If this contains "Y" / "N" you have to do something kind of like this code sample:

void Method()
{
 string arr = new[] { "Y", "n", "N", "y"};

 foreach (string value in arr)
 {
    // If it DOES equal "y", then this is "true"; otherwise "false"
    bool boolean = value.Trim().ToLower().Equals("y");
 }
}

Trying to do something like bool.Parse("Y") will definitely throw an exception.

The weakness of the code sample above is that if the data is bad (i.e. it contains something other than a "Y" or "N") it won't detect that.

public static SalesInfo Parse(string stringValue)
{
    string[] words;
    SalesInfo salesInfo = new SalesInfo();

    words = StringMethods.ParseCsvString(stringValue.Trim());
    salesInfo.ID = int.Parse(words[0]);
    salesInfo.Name = words[1];
    salesInfo.City = words[2];
    // Solution here
    salesInfo.Senior = words[3].Trim().ToLower().Equals("y");
    salesInfo.Veteran = bool.Parse(words[4]);
    salesInfo.PurDate = Date.Parse(words[5]);
    salesInfo.ItemPrice = Double.Parse(words[6]);
    salesInfo.Quantity = int.Parse(words[7]);

    return salesInfo;
}

I like Steve's approach a lot as well. One possible variant is as follows:

public bool ParseBool(string input)
{
   if (input == null)
      throw new ArgumentNullException("input");

   switch (input.ToLower())
   {
       case "y":
       case "yes":
           return true;

       case "n":
       case "no":
            return false;

       // If the CSV file is wrong (i.e. it contains "bad" data)
       default:
           return throw new ArgumentException("bad data - not a bool");
    }
}