In C# (as in C and C++), the backslash character ("\") has special
meaning: it is an "escape" that combines with the character after it to
make a special character that you can't type into your program. Some
famous uses of it, all the way back to C, are \n for a newline
(linefeed) control character, and \0 meaning the character with value 0
(the NUL control character).
So, any time you type a string and put a backslash \ in it, the
compiler thinks that you want to indicate a special character, and
tries to combine the backslash with the following character to create
something else.
However, what if you really want a backslash character in your string?
What if you want \n to mean not a newline control character, but really
a backslash followed by an en? Then you have to use a double-backslash,
\\, which the compiler reads as a special sequence that folds down into
a single backslash in the string itself.
Take a look at the following code:
string a = "\n";
string b = "\\n";
The string called "a" contains a _single character_: a newline, or
linefeed control character, because the sequence backslash-en is
interpreted by the compiler as a request for this special character.
The string called "b" contains _two characters_: a backslash, which the
compiler put into the string because it saw the "escaped backslash"
sequence: two backslashes in a row... followed by an en character.
Now in C and C++ this was all there was to it: everywhere in your
string that you wanted a single backslash character, you had to type
two into your program so that the compiler would know what to do. If
you wanted two, you would have to type four into your program, etc.
(Note that this is only the _compiler_ doing this, not the runtime. So,
if you read in a line from a file that has the characters "\n" on it,
these do _not_ get folded into a newline character, because the
_compiler_ isn't reading the file... your program is.)
However, because C# runs on the Windows operating system, and Windows
traditionally uses backslash to separate directory names in file paths,
Microsoft realized that forcing you to type double-backslashes for
every backslash you wanted in a hard-coded string in your program was
going to be... well, a pain in the ass. So, they added a new marker,
the "@" marker.
When you put an "@" at the beginning of a string, it means, "Compiler:
there are no special characters in this string. Don't do your normal
special-character processing on this one. Just put exactly what I type
into the string." So, the declaration for string "b" above could be
changed to:
string b = @"\n";
which produces the same thing internally: a two-character string
containing a backslash and an en.
In answer to your specific question, the compiler gives you an error
because you said:
int n = str_old.IndexOf('\');
In this case, the backslash indicates a special character sequence, and
the following character is a single quote. That tells the compiler that
you really want a single quote mark in the character sequence, and that
the single quote that directly follows the backslash is _not_ the
ending delimiter for the character sequence. So, the compiler goes on
adding characters to the sequence (closed parenthesis, then semicolon)
until it arrives at the end of the line and realizes that something
went wrong. In effect, you never ended the character constant because
you told the compiler that the second single quote was "special" by
preceding it with a backslash.
As Joakim pointed out, you could fix this by either doubling the
backslash, a la C:
int n = str_old.IndexOf('\\');
or adding the "@" marker to the start, to tell the compiler not to
treat the backslash specially:
int n = str_old.IndexOf(@'\');