Concatenating strings using the ternary operator

I create a SelectList various contacts. I want the displayed text to be a combination of FirstName , MiddleInit (if possible) and LastName .

 IEnumerable<SelectListItem> items = contacts .Select(r => new SelectListItem() { Value = r.ContactID.ToString(), Text = r.FirstName + " " + string.IsNullOrEmpty(r.MiddleInit) ? r.MiddleInit + ". " : "" + r.LastName }); 

I get an error message:

 Error 4 Cannot implicitly convert type 'string' to 'bool' C:\Users\cu551d\Documents\Visual Studio 2010\Projects\WVM\WVM\Controllers\SOWController.cs 181 15 WVM 

I guess this has something to do with my syntax. Can I do something like this in C #?

Also, should I include the Trim() operator in MiddleInit ? I thought this error was very strange since IsNullOrEmpty really returns a bool. I also tried (string.IsNullOrEmpty(r.MiddleInit) == true ) ..

+6
source share
4 answers

Try grouping in parentheses. It also looks like you are executing a conditional statement backwards:

 IEnumerable<SelectListItem> items = contacts .Select(r => new SelectListItem() { Value = r.ContactID.ToString(), Text = r.FirstName + " " + (string.IsNullOrEmpty(r.MiddleInit) ? "" : (r.MiddleInit + ". ")) + r.LastName }); 

Other technique

Since you are converting it to an empty string anyway, you might also think about this:

 Text = r.FirstName + " " + (r.MiddleInit ?? "") + r.LastName 

?? called Null Coalescing Operator . It will return everything that is on the left if this value is not null, otherwise no matter what is on the right.

http://msdn.microsoft.com/en-us/library/ms173224.aspx

EDIT : while cleaner, this will not work for your case, since you need a period after the initial one. But keep in mind that it exists!

+14
source

The problem is with operator precedence, forcing the compiler to parse the expression in a way you don't expect. Just wrapping the ternary expression in parens will politely explain to the compiler what you want to say.

As a side note, looking at the logic of an expression, I think the order of the terms of the result is incorrect. I have included them in the code below.

 IEnumerable<SelectListItem> items = contacts .Select(r => new SelectListItem() { Value = r.ContactID.ToString(), Text = r.FirstName + " " + (string.IsNullOrEmpty(r.MiddleInit) ? "" : r.MiddleInit + ". ") + r.LastName }); 

Additional Information

Without ( , + has a higher priority than ?: So the expression in your question is parsed as if it were saying:

 Test = (r.FirstName + " " + string.IsNullOrEmpty(r.MiddleInit)) ? (r.MiddleInit + ". ") : ("" + r.LastName) 

So, the source of your error is that the conditional part of the ?: Statement is actually a string that will contain something like "Andrew true". Also note that r.LastName combined with the third member of the ?: Operator.

Question Trim ()

If it is likely that r.MiddleInit may contain spaces, then using Trim() will help, but it would be better to change the test to String.IsNullOrWhiteSpace(r.MiddleInit) .

+6
source

Try to wrap your arguments in triple

 IEnumerable<SelectListItem> items = contacts .Select(r => new SelectListItem() { Value = r.ContactID.ToString(), Text = r.FirstName + " " + (string.IsNullOrEmpty(r.MiddleInit) ? (r.MiddleInit + ". ") : ("" + r.LastName)) }); 
+1
source

You do not need to wrap the arguments, just triple ...

 IEnumerable<SelectListItem> items = contacts .Select(r => new SelectListItem() { Value = r.ContactID.ToString(), Text = r.FirstName + " " + (string.IsNullOrEmpty(r.MiddleInit) ? r.MiddleInit + ". " : "") + r.LastName }); 

I found by trying what I really need ...

 (!string.IsNullOrEmpty(r.MiddleInit) ? r.MiddleInit + ". " : "") 

so that it works correctly.

+1
source

All Articles