Burned by Ternary Operators
September 16, 2013 in C#First let me say that I’m not a fan of ternary operators. I try to avoid them because I feel that an explicit if/else is much more readable. I do use them on occasion and this seemed like the perfect place for them.
I ran into a interesting problem while trying to get a Linq where clause to work with ternary operators. In hindsight the problem is pretty obvious, but it stumped me and one of my coworkers for a few minutes. It wasn’t until we solved the problem in a different way that I realized what I had initially missed.
First the setup:
var books = new List<Book>();
books.Add(new Book { Title = "To Kill a Mockingbird", Description = null });
books.Add(new Book { Title = "Catcher in the Rye", Description = null });
There where clause I was building was part of some basic search functionality. It would take a passed in value and check to see if the Title or the Description contained that value:
var qry = books.Where(u =>;
u.Description == null ? false : u.Description.ToUpper().Contains(searchStr)
|| u.Title == null ? false : u.Title.ToUpper().Contains(searchStr)
);
Attempts to search for the letter T were returning no results. Like I said, I struggled with it, called in a second set of eyes and they couldn’t see the problem. We then re-wrote where clause like this:
var qry = books.Where(u =>;
(u.Description != null && u.Description.ToUpper().Contains(searchStr))
|| (u.Title != null && u.Title.ToUpper().Contains(searchStr))
);
This returned 2 results as expected. After a bit of rumination I realized the problem was my lack of parentheses. I thought I had written this:
var qry = books.Where(u =>;
(u.Description == null ? false : u.Description.ToUpper().Contains(searchStr))
|| (u.Title == null ? false : u.Title.ToUpper().Contains(searchStr))
);
When I had essentially written this:
var qry = books.Where(u =>
u.Description == null ? false :
(
u.Description.ToUpper().Contains(searchStr)
|| u.Title == null ? false : u.Title.ToUpper().Contains(searchStr)
)
);
This was clearly just my misunderstanding of how ternary operators are interpreted, and I’m unlikely to ever forget this, but I’m also going to continue to avoid ternary operators wherever I can and encourage others to do the same.
Have a comment or suggestion? This blog takes pull requests.Or you can just open an issue.