11

I think that my code should make the ViewBag.test property equal to "No Match", but instead it throws an InvalidOperationException.

Why is this?

string str = "Hello1,Hello,Hello2";
string another = "Hello5";
string retVal = str.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                   .First(p => p.Equals(another));
if (str == another)
{
   ViewBag.test = "Match";
}
else
{
   ViewBag.test = "No Match"; //this does not happen when it should
}
Léo Natan
  • 56,823
  • 9
  • 150
  • 195
user2398766
  • 123
  • 1
  • 2
  • 5
  • @SLaks The code returns System.InvalidOperationException instead of diplay "No Match" on the page. – user2398766 May 19 '13 at 15:41
  • It doesn't **return** `InvalidOperationException`, it throws it. Mainly because there is no string in that list that is equal to "Hello5". What are you tring to accomplish? – It'sNotALie. May 19 '13 at 15:51
  • 2
    .First() throws it, if there isn't a match, try FirstOrDefault() and check null – Laszlo Boke May 19 '13 at 15:53

2 Answers2

18

As you can see here, the First method throws an InvalidOperationException when the sequence on which it is called is empty. Since no element of the result of the split equals Hello5, the result is an empty list. Using First on that list will throw the exception.

Consider using FirstOrDefault, instead (documented here), which, instead of throwing an exception when the sequence is empty, returns the default value for the type of the enumerable. In that case, the result of the call will be null, and you should check for that in the rest of the code.

It might be cleaner still to use the Any Linq method (documented here), which returns a bool.

string str = "Hello1,Hello,Hello2";
string another = "Hello5";
bool retVal = str.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                   .Any(p => p.Equals(another));
if (retVal)
{
   ViewBag.test = "Match";
}
else
{
   ViewBag.test = "No Match"; //not work
}

And now the obligatory one liner using the ternary operator:

string str = "Hello1,Hello,Hello2";
string another = "Hello5";
ViewBag.test = str.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                   .Any(p => p == another) ? "Match" : "No Match";

Note that I also used == here to compare strings, which is considered more idiomatic in C#.

Ben Reich
  • 16,222
  • 2
  • 38
  • 59
  • 2
    I **would** upvote this, but the code's unclear I have absolutely no idea what (s)he's trying to do. – It'sNotALie. May 19 '13 at 15:57
  • 1
    I interpreted the question such that that he or she is trying to set `ViewBag.test` to "Match" when the variable `str` contains the variable `another` in between commas, and "No Match" otherwise. Is that what you meant, @user2398766? – Ben Reich May 19 '13 at 16:02
  • I agree with that, but I can't tell! – It'sNotALie. May 19 '13 at 16:04
2

Give this a shot:

bool hasMatch = str.Split(',').Any(x => x.Equals(another));

ViewBag.test = hasMatch ? "Match" : "No Match";
Dimitar Dimitrov
  • 14,868
  • 8
  • 51
  • 79