C#, VB.NET, and echoing strings in the VS.NET Immediate Window

November 28, 2005

I've become rather agnostic on the whole topic of C# versus VB.NET, but there are still those annoying little differences that sneak up behind you and rabbit-punch you in the kidneys. Like, say, using the VS.NET 2003 command window in immediate mode to print a string:

Printing text in the Immediate window in a C# project

Printing text in the Immediate window in a VB.NET project

Usually VB.NET is guilty of handling things in odd and unexpected ways, but this time it's C#. I expect newlines to appear in the immediate window as, oh, I don't know.. NEW LINES? It's a bit difficult to read text filled with a bunch of \r\n notation instead of human readable whitespace. What's worse is that even the variable tooltips in C# behave this way!

How can I work around this annoying "feature" of the C# IDE? I thought about creating a macro to use ?System.Diagnostics.Debug.WriteLine(s), which behaves appropriately, but the Diagnostics class isn't always in scope at a breakpoint.

Posted by Jeff Atwood
11 Comments

I like how the immediate/watch window bombs if you chain more than 3-ish statements together.

David Grant on November 29, 2005 4:04 AM

The "cheese factor" of this solution rates an 11 on a scale of 1 - 10, but it is only meant to get your creative juices flowing...

I assume that the sample line of code in your Immediate window, would actually be a line of source code (and you would have had to copy / paste it, or worse yet, type it in the Immediate window)...

Rather than copy / paste the line of code into the Immediate window, I personally would just like to highlight the string in the source code editor, and then have the results of it evaluated and printed out to the Immediate window.

So, I have started the macro below... To try this out:

1) Copy / Paste the code into a new macro project.
2) From the VS.NET IDE, assign the macro a shortcut key (Tools - Options - Keyboard).
3) Set a breakpoint somewhere in your app and run the C# app that contains the sample "Environment.NewLine + "Hello World" + Environment.NewLine" of code.
4) Or heck, don't run the project. Doesn't matter. Just highlight your sample line of source code.
5) If you ran your app, when the breakpoint is hit, highlight your exact sample string in the source code editor (not including the semi-colon end of line character).
5) Hit the shortcut key that you assigned to the macro.

Expected Result:
In the Immediate Window, you should see a blank line, then your text, then a blank line printed out...

OK, so you'll notice that it doesn't quite print in the expected location (I think it prints above the last line in the window).

And you'll notice that I hardcoded this to search for the string "NewLine" in the macro's "IndexOf" method...

But heck, this is just an example of how you can control / write to the Immediate window, and write newlines to it. Since you are trying to solve a very specific problem in your example, coding a specific string is ugly, but works.


Macro Code:
-------------------------
Imports EnvDTE
Imports System.Diagnostics
Imports Microsoft.VisualBasic
Imports Microsoft.VisualBasic.ControlChars

Public Module OutputString

Public Sub OutputFullString()

Dim i As Integer
Dim c As Char = "+"

Dim Selection As TextSelection = DTE.ActiveDocument.Selection
Dim EvalText As String = Selection.Text
Dim Strings() As String = E v a l Text . Split(c)

Dim win As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindCommandWindow)
Dim CW As CommandWindow = win.Object

For i = 0 To Strings.Length - 1
If Strings(i).ToString.IndexOf("NewLine") 1 Then
CW.OutputString(System.Environment.NewLine)
Else
CW.OutputString(Strings(i).ToString)
End If
Next

End Sub

End Module

Brent Hetland on November 30, 2005 4:59 AM

Take it a step further and compare the C# IDE to the VB.NET IDE. For instance, the C# IDE fails to display intellisense if you have ONE FREAKING ERROR ANYWHERE ON THE PAGE. VB.NET, yeah, intellisense works when you need it to. I was forced to switch to C# (which hasn't been that hard really) from VB 6/VB.NET, and the IDE is what is killing me. I could care less about the squiggly brackets and syntax in general (easy to adapt if you know HOW TO CODE). I wish the IDE behaved the same between the two languages, but I know why. It's how C# works. Period.

Brian Swiger on November 30, 2005 10:42 AM

Sorry, I don't have a solution, but can I say I like the C# way more? It's unambiguous. What if the variable contains just "\r", how would you want it to be displayed? With a line break or not? What if you're debugging string parsing code and need to differentiate between tabs and spaces?

In VS 2005 C# we get the best of two approaches: it displays codes for non-printable characters in variable tooltips and immediate window, but shows formatted text in pop-up text visualizer.

Alexander Shirshov on December 1, 2005 2:49 AM

I had a similar issue recently while working with some XML code. What I wanted to do was dump the contents of a document or an element or whatever into the immediate window, and copy-paste it into XMLSpy. When I used ?node.OuterXml I discovered that all the quotes were backslashed. I ended up calling System.Diagnostics.Debug.WriteLine(). Of course, document.Save() would have also done, but I feel a bit of extensibility-model-hacking coming on.

Dominic Cronin on December 3, 2005 1:56 AM

You want the ever discoverable format specifier:

?Environment.NewLine + "Hello World!"
"\r\nHello World!"
?Environment.NewLine + "Hello World!",nq

Hello World!

Steve Steiner on May 17, 2006 6:08 AM

Oh and here is a pointer to the documentation for C# format specifiers:

http://msdn2.microsoft.com/en-us/library/e514eeby.aspx

Steve Steiner on May 17, 2006 6:19 AM

blahhh blahhh blahhh.... C# is for REAL CODERS as oppose to VB, if you ever studied programming in college (as oppose to reading a VB for dummies and calling yourself a programmer) you will know the essence of coding in a real language like C#. VB was designed for the weak and timid minded programmers. If you don't like coding in C# then DON'T and crawl back to your VB cave, and stop complaining.. ohhh my intellisense does not work,, ohhh i can't find documentation to spoon feed me the information....

cheers..

Bit_flipper on July 28, 2008 8:08 AM

here is the solution u DIM minded vb-coders... DIM just like your types... lol

string[] tmp = s.Replace(\r, string.Empty).Split('\n');

u cann't just use s.Replace(\r, string.Empty).Split('\n'); without assigning to something... read the return type you DIMs...


Bit_flipper on July 28, 2008 8:16 AM

ohhh i can't find documentation to spoon feed me the information....

ohhh I ironically can't properly capitalize or form grammatically correct sentences in my flames against unsophisticated VB programmers.


And actually we're not having any trouble finding the documentation, the key is finding my baseball bat, then we'll C just how sharp you are. Besides, it's not VB anymore. It's no longer a conglomerate mess of backward compatible features going all the way back to Goto and GoSub.

would the code:s.Replace(\r, string.Empty).Split('\n'); work if that result was used in a call to Join (or is join not in .NET? I really have to start it up someday...)

BASeCamper on August 28, 2008 10:19 AM

Here's a thought on how to do this, but I cannot get it to work yet. If you perform this operation on the string s:

s.Replace("\r", string.Empty).Split('\n')

And evaluate it, you get a nice list of lines in an ordered list(zero-based of course), that looks like this:

{Length=3}
[0]: ""
[1]: "Hello World!"
[2]: ""

However, I cannot get it to work because, for whatever reason, you cannot evaluate Split and Replace in the immed window.

Just a thought on the topic, as it is something very aggrevating to me as well.

Marty Thompson on February 6, 2010 9:46 PM

The comments to this entry are closed.