views:

543

answers:

11

Is there a decent way to declare a long single line string in C#, such that it isn't impossible to declare and/or view the string in an editor?

The options I'm aware of are:

1: Let it run. This is bad because because your string trails way off to the right of the screen, making a developer reading the message have to annoying scroll and read.

string s = "this is my really long string.  this is my really long string.  this is my really long string.  this is my really long string.  this is my really long string.  this is my really long string.  this is my really long string.  this is my really long string.  ";

2: @+newlines. This looks nice in code, but introduces newlines to the string. Furthermore, if you want it to look nice in code, not only do you get newlines, but you also get awkward spaces at the beginning of each line of the string.

string s = @"this is my really long string.  this is my long string.
             this line will be indented way too much in the UI. 
This line looks silly in code.  All of them suffer from newlines in the UI.";

3: "" + ... This works fine, but is super frustrating to type. If I need to add half a line's worth of text somewhere I have to update all kinds of +'s and move text all around.

string s = "this is my really long string.  this is my long string. " + 
           "this will actually show up properly in the UI and looks " +
           "pretty good in the editor, but is just a pain to type out " +
           "and maintain";

4: string.format or string.concat. Basically the same as above, but without the plus signs. Has the same benefits and downsides.

Is there really no way to do this well?

+47  A: 

There is a way. Put your very long string in resources. You can even put there long pieces of text because it's where the texts should be. Having them directly in code is a real bad practice.

Developer Art
I like to change my VS colour scheme so that strings show up in some hideous colour. Always reminds me that something bad is happening.
DavidGouge
Bad practice yes, but not always fixablen in legacy software (where the project manager hasn't seen the light).
Stevo3000
@Stevo3000: I believe the question author is in a position to fix it. That's why he asking for advice.
Developer Art
+1 though it may not always be a bad practice...think about the strings which are meant for the developers only and are never seen by the user (for example those used for diagnostic purposes). The (effort) overhead of maintaining them as a resource may not be worth it.
SDX2000
I was just adding for the sake of completeness (for somone finding this answer through google e.t.c.) that this wasn't always possible. I gave +1 just like everyone else.
Stevo3000
-1 on that. It does not answer the question, plus suggests a misleading "best" practice, which is questionable (e.g. see SDX2000's comment).
Vytautas Shaltenis
Agreed, this is a fine solution, but is there any way to do this inline? I'm hesitant to rephrase the question since this is probably the "best" answer. Based on everyone else's responses it sounds like the answer is "there is no good way".
Cory
A: 

You could use StringBuilder

Jimmeh
+8  A: 

If using Visual Studio

Tools > Options > Text Editor > All Languages > Word Wrap

I'm sure any other text editor (including notepad) will be able to do this!

Stevo3000
I like that option for code, but not for huge strings like this
CodeByMoonlight
@CodeByMoonlight - What is a long string in source code but code? I'm not saying that it's the right aproach, but it does what it says on the tin! Personally I would store strings as a resource!
Stevo3000
I use this option constantly, it just feels wrong for long strings that might cover several screens. The resource option is better, as has been said.
CodeByMoonlight
A: 

I either just let it run, or use string.format and write the string in one line (the let it run method) but put each of the arguments in new line, which makes it either easier to read, or at least give the reader some idea what he can expect in the long string without reading it in detail.

Rekreativc
Alternatively, break up the really long string and use `string.Concat` to join the pieces. That avoids the excessive `+`-ness of the right side :-)
Joey
+5  A: 

Does it have to be defined in the source file? Otherwise, define it in a resource or config file.

d91-jal
+3  A: 

you can use StringBuilder like this:

StringBuilder str = new StringBuilder();
str.Append("this is my really long string.  this is my long string. ");
str.Append("this is my really long string.  this is my long string. ");
str.Append("this is my really long string.  this is my long string. ");
str.Append("this is my really long string.  this is my long string. ");
string s = str.ToString();

You can also use: Text files, resource file, Database and registry.

Wael Dalloul
Dunno why this response was rated so low. It has example code, and using StringBuilder is a good practice to be in, as over many concatenations, it is more efficient.
Ogre Psalm33
Because in this situation it just adds unnecessary complication.
CodeByMoonlight
I'm not sure there's enough context in the question to determine the situation. Is this a one-off message at application start-up? Or is it a log message in a method being called 100 times a second? In that case, performance matters. Reference actual performance measurements: http://blog.briandicroce.com/2008/02/04/stringbuilder-vs-string-performance-in-net/
Ogre Psalm33
@Ogre: Concatenation of string *literals* is handled by the C# compiler. Using a `StringBuilder` would actually be slower that using `"x"+"y"`, where the latter has zero runtime overhead.
280Z28
+1 This answer seems underrated.
J.Hendrix
+2  A: 

Personally I would read a string that big from a file perhaps an XML document.

James
+1  A: 

For really long strings, I'd store it in XML (or a resource). For occasions where it makes sense to have it in the code, I use the multiline string concatenation with the + operator. The only place I can think of where I do this, though, is in my unit tests for code that reads and parses XML where I'm actually trying to avoid using an XML file for testing. Since it's a unit test I almost always want to have the string right there to refer to as well. In those cases I might segregate them all into a #region directive so I can show/hide it as needed.

tvanfosson
A: 

if you really needed to keep it in the code then how about @+newlines and then a simple function to strip out the newlines.

Hassan Voyeau
+2  A: 

It depends on how the string is going to wind up being used. All the answers here are valid, but context is important. If long string "s" is going to be logged, it should be surrounded with a logging guard test, such as this Log4net example:

if (log.IsDebug) {
    string s = "blah blah blah" + 
    // whatever concatenation you think looks the best can be used here,
    // since it's guarded...
}

If the long string s is going to be displayed to a user, then Developer Art's answer is the best choice...those should be in resource file.

For other uses (generating SQL query strings, writing to files [but consider resources again for these], etc...), where you are concatenating more than just literals, consider StringBuilder as Wael Dalloul suggests, especially if your string might possibly wind up in a function that just may, at some date in the distant future, be called many many times in a time-critical application (All those invocations add up). I do this, for example, when building a SQL query where I have parameters that are variables.

Other than that, no, I don't know of anything that both looks pretty and is easy to type (though the word wrap suggestion is a nice idea, it may not translate well to diff tools, code print outs, or code review tools). Those are the breaks. (I personally use the plus-sign approach to make the line-wraps neat for our print outs and code reviews).

Ogre Psalm33
Concatenation of string literals is handled by the C# compiler, so there's zero overhead at runtime for using a string declared as `"x"+"y"+"Z"+...`
280Z28
Ah, @280Z28 is of course correct! I added some clarification as to when to use the StringBuilder approach (when you have variables mixed in with your ltierals).
Ogre Psalm33
+1  A: 

If you really want this long string in the code, and you really don't want to type the end-quote-plus-begin-quote, then you can try something like this.

string longString = @"Some long string, 
    with multiple whitespace characters 
    (including newlines and carriage returns)
    converted to a single space
    by a regular expression replace.";

longString = Regex.Replace(longString, @"\s+", " ");
John Fisher