Click here to Skip to main content
15,882,017 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more: , +
C#
sb.Append("<tr><td>Call Time: " + searchResult[i].CreatedDate != null ? Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt") : "" + "</td></tr>");


in the above code when i remove below code then tr is showing otherwise it showing Time not label "Call Time:"

C#
" + searchResult[i].CreatedDate != null ? Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt") : "" + "


Example:If i use the uppermost code then it's showing 1:00 PM only but actual data will be Call Time: 1:00 PM.When i remove the datavalue then it's showing Call Time:

In the above code sb is StringBuilder.

Why it's happening in stringbuilder i am unable to find.


Plz help.
Thank u.
Posted
Updated 19-May-15 4:27am
v3

Mind the operator precedence[^] - conditional operator has very low priority and only comes after + (concatenation). You can either use parentheses to change the evaluation or split it into multiple statements.
C#
sb.Append("<tr><td>Call Time: " + (searchResult[i].CreatedDate != null ? Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt") : "") + "</td></tr>");

C#
var callTime = searchResult[i].CreatedDate != null ? Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt") : "";
sb.Append("<tr><td>Call Time: " + callTime + "</td></tr>");

BTW it would be much nicer to use properties Value and HasValue of the nullable DateTime:
C#
var createdDate = searchResult[i].CreatedDate;
var callTime = createdDate.HasValue ? createdDate.Value.ToString("hh:mm tt") : "";
 
Share this answer
 
v2
Comments
Richard Deeming 19-May-15 10:38am    
Snap! :)
Andy Lanng 19-May-15 10:39am    
Doh! too late :Þ
Sergey Alexandrovich Kryukov 19-May-15 10:44am    
Yes, a 5.
I provided general instructions but did not point out this problem; please see.
—SA
This is due to operator precedence. Your code is equivalent to:
C#
if (("<tr><td>Call Time: " + searchResult[i].CreatedDate) != null)
{
    sb.Append(Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt"));
}
else
{
    sb.Append("" + "</td></tr>");
}

Since anything appended to a non-null string will always produce a non-null value, you're always going to end up in the first branch.
Ignore that line - it's totally wrong.

Either split the code in to multiple lines:
C#
sb.Append("<tr><td>Call Time: ");
if (searchResult[i].CreatedDate != null)
{
    sb.Append(Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt"));
}
sb.Append("</td></tr>");

or add parentheses to force the precedence:
C#
sb.Append("<tr><td>Call Time: " + (searchResult[i].CreatedDate != null ? Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt") : "") + "</td></t>");

or use AppendFormat:
C#
sb.AppendFormat("<tr><td>Call Time: {0:hh:mm tt}</td></t>", searchResult[i].CreatedDate);
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 19-May-15 10:44am    
5ed.
—SA
Tomas Takac 19-May-15 10:48am    
+5, AppendFormat is definitely the most elegant way
Brackets!
C#
//this
sb.Append("<table><tbody><tr><td>Call Time: " + searchResult[i].CreatedDate != null ? Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt") : "" + "</td></tr></tbody></table>");
//is like this
sb.Append(("<table><tbody><tr><td>Call Time: " + searchResult[i].CreatedDate != null ? Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt") : "") + "</td></tr></tbody></table>");

//you need this
sb.Append("<table><tbody><tr><td>Call Time: " + (searchResult[i].CreatedDate != null ? Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt") : "") + "</td></tr></tbody></table>");
 
Share this answer
 
Operator precedence is the key here...
Try this:
C#
object o = null;
string s = "1" + o == null ? "2" : "3" + "4";
string t = "1" + o != null ? "2" : "3" + "4";
And compare the values of s and t
s: "34"
t: "2"

The reason for this is that the "+" has a higher precedence than "?" - so the beginning bit is swallowed.
Adding brackets to override the precedence:
C#
object o = null;
string s = "1" + (o == null ? "2" : "3") + "4";
string t = "1" + (o != null ? "2" : "3") + "4";
Gives the values you expect:
s: "124"
t: "134"

So add the brackets to your code, and it should work:
C#
sb.Append("<tr><td>Call Time: " + (searchResult[i].CreatedDate != null ? Convert.ToDateTime(searchResult[i].CreatedDate).ToString("hh:mm tt") : "") + "</td></tr>");
 
Share this answer
 
The problem looks simple like hell. First of all, it makes no sense to ask questions about StringBuilder behavior if you are showing only one string in your code sample. Believe me, StringBuilder does not do anything wrong; it simply adds the string; there is no point in seeing what's happening in its instance. Instead, look at your string.

How can you try to make your code in one like and complain about difficulties in debugging at the same time. If you really want to debug, write your string step by step and have a separate variable for the resulting string.

Never repeat any code. Therefore, calculate searchResult[i].CreatedDate separately, assign the result to a different variable. Always, even in your working code, not just for debugging. And then assign the string in the middle, the one you obtain from ToString and the conditional operator, to a separate string variable. Inspect it under the debugger. Let's say, this is the variable myMiddleString (don't name it like that in real code, of course; always use semantic names).

And finally, what's the point of using so performance-improving tool as StringBuilder, if you are using such a performance-killing thing as multiple string concatenation? Of course, this performance leak is minor compared to the StringBuilder gain, but nevertheless; you can also improve readability. Don't do it! Use
C#
string myStringToAdd = string.Format("<tr><td>Call Time: {0}</td></tr>", myMiddleString);


And then you can see what's going on in the debugger. StringBuilder is irrelevant here.
Now, about HTML: from your sample, it's apparent that you are creating table rows with one cell each; it does not seem to make much sense.

Otherwise, the idea of your code looks correct. Your particular problem is explained in other answers, please see them.

—SA
 
Share this answer
 
v2
Comments
itsathere 19-May-15 11:48am    
Thanks.
Sergey Alexandrovich Kryukov 19-May-15 13:32pm    
You are welcome.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900