0

How do I escape with the @-sign when using variables?

File.Delete(@"c:\test"); // WORKS!

File.Delete(@path); // doesn't work :(

File.Delete(@"c:\test"+path); // WORKS

Anyone have any idea? It's the 2nd example I want to use!

Dave
  • 253
  • 6
  • 14
  • 3
    *Why* do you want to use the second example? – Lasse V. Karlsen Aug 08 '14 at 09:22
  • Why do you need to use a literal string here? It should make zero difference to the `File.Delete` call... – James Aug 08 '14 at 09:22
  • @Lasse: I guess they think that prepending something with `@` is magic to make paths in strings work. Cargo-culting that as »Always prepend paths with `@`, otherwise they don't work«. I can see how one without proper instruction or training might think that, completely oblivious to the actual language features that make that work. And to the compiler `@path` isn't wrong either, just for other reasons. – Joey Aug 08 '14 at 09:25
  • You need to note that your third example is equivalent to `(@"c:\test") + path` – Sayse Aug 08 '14 at 09:25
  • @James This was just en example. I just took a random function at the top of my head to make an example of – Dave Aug 08 '14 at 09:26
  • What is the contents of `path`? – Lasse V. Karlsen Aug 08 '14 at 09:26
  • And don't post random questions bearing no resemblance to the actual problem. You will only get answers to your posted question, not to your actual problem. – Lasse V. Karlsen Aug 08 '14 at 09:28

5 Answers5

3

Strings prefixed with @ character are called verbatim string literals (whose contents do not need to be escaped).

Therefore, you can only use @ with string literals, not string variables.

So, just File.Delete(path); will do, after you assign the path in advance of course (from a verbatim string or some other string).

Marcel N.
  • 13,726
  • 5
  • 47
  • 72
3

Verbatim strings are just a syntactic nicety to be able to type strings containing backslashes (paths, regexes) easier. The declarations

string path = "C:\\test";
string path = @"C:\test";

are completely identical in their result. Both result in a string containing C:\test. Note that either option is just needed because the C# language treats \ in strings as special.

The @ is not some magic pixie dust needed to make paths work properly, it has a defined meaning when prefixed to strings, in that the strings are interpreted without the usual \ escape sequences.

The reason your second example doesn't work like you expect is that @ prefixed to a variable name does something different: It allows you to use reserved keywords as identifiers, so that you could use @class as an identifier, for example. For identifiers that don't clash with keywords the result is the same as without.

If you have a string variable containing a path, then you can usually assume that there is no escaping needed at all. After all it already is in a string. The things I mentioned above are needed to get text from source code correctly through the compiler into a string at runtime, because the compiler has different ideas. The string itself is just data that's always represented the same.

This still means that you have to initialise the string in a way that backslashes survive. If you read it from somewhere no special treatment should be necessary, if you have it as a constant string somewhere else in the code, then again, one of the options at the top has to be used.

Joey
  • 344,408
  • 85
  • 689
  • 683
2
string path = @"c:\test"; 
File.Delete(path); 

This will work only on a string. The "real" string is "c:\\test".

Read more here.

Community
  • 1
  • 1
Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
2

There's a major problem with your understanding of the @ indicator.

@"whatever string" is a literal string specifier verbatim string literal. What it does is tells the C# compiler to not look for escape sequences. Normally, "\" is an escape sequence in a string, and you can do things like "\n" to indicate a new line or "\t" to indicate a tab. However, if you have @"\n", it tells the compiler "no, I really want to treat the backslash as a backslash character, not an escape sequence."

If you don't like literal mode, the way to do it is to use "\\" anywhere you want a single backslash, because the compiler knows to treat an escaped backslash as the single character.

In either case, @"\n" and "\\n" will produce a 2-character string in memory, with the characters '\' and 'n'. It doesn't matter which way you get there; both are ways of telling the compiler you want those two characters.

In light of this, @path makes no sense, because you don't have any literal characters - just a variable. By the time you have the variable, you already have the characters you want in memory. It does compile ok, as explained by Joey, but it's not logically what you're looking for.

If you're looking for a way to get rid of occurrences of \\ within a variable, you simply want String.Replace:

string ugly = @"C:\\foo";
ugly = ugly.Replace(@"\\", @"\");
Scott Mermelstein
  • 15,174
  • 4
  • 48
  • 76
  • Nice answer. But `@"whatever string"`'s technical term is ***verbatim string literal***, not _literal string_. – sampathsris Aug 08 '14 at 09:43
  • @Scott Mermelstein You don't have to be rude about my understanding of the @ indicator. I was asking for help, not your opinion about my lack of skills. – Dave Aug 08 '14 at 11:25
  • @DavidLarsson I try to avoid being rude, and I'm sorry if you perceived me as such. Are you saying that there wasn't a major problem with your understanding of the `@`? That strikes me as the most rude of my statements. – Scott Mermelstein Aug 08 '14 at 16:16
  • @krumia For some reason, when I saw the proper term in Marcel's answer, I didn't want to go back and change mine, but I've now fixed it in my answer. – Scott Mermelstein Aug 08 '14 at 18:49
  • @DavidLarsson: By StackOverflow's standards, I don't think he was being rude. We do not necessarily count lack of understanding of something as lack of skills. :) It was evident from your question that you lacked the understanding, (which is _totally fine_ BTW). – sampathsris Aug 09 '14 at 00:40
  • Yeah, you might be right. I just felt that, that had nothing to do with my question. I was asking because I did lack the knowledge yeah, but when you open with "There's a major problem with your understanding of the ..." on the internetz you take it as it was meant offensive. Since it has nothing to do with the subject, nor helping :( I did like @Scott's answer and as he said he didn't mean to be rude. Even if it came out like it, which happens I guess. – Dave Aug 19 '14 at 12:21
0

First and third are actual paths hence would work.

Second would not even compile and would work if

 string path = @"c:\test";
 File.Delete(path);
Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208