Dave
Dave

Reputation: 253

Properly escape filepaths

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!

Upvotes: 0

Views: 93

Answers (5)

Scott Mermelstein
Scott Mermelstein

Reputation: 15397

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(@"\\", @"\");

Upvotes: 2

Amir Popovich
Amir Popovich

Reputation: 29836

string path = @"c:\test"; 
File.Delete(path); 

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

Read more here.

Upvotes: 2

Joey
Joey

Reputation: 354576

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.

Upvotes: 3

Marcel N.
Marcel N.

Reputation: 13976

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).

Upvotes: 3

Nikhil Agrawal
Nikhil Agrawal

Reputation: 48568

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);

Upvotes: 0

Related Questions