C# 为什么System.Uri将一行中的两个斜杠解释为文件夹?

C# 为什么System.Uri将一行中的两个斜杠解释为文件夹?,c#,.net,uri,backslash,slash,C#,.net,Uri,Backslash,Slash,我已经养成习惯,总是在文件夹路径的末尾放一个尾随斜杠,这似乎是惯例(例如,Visual Studio宏,如$(ProjectDir)总是有一个尾随斜杠)。此外,当我将相对路径附加到现有文件夹路径的末尾时,我总是放一个前导斜杠,以防传递给我的文件夹路径没有尾随斜杠(例如,Windows批处理:设置完整\u文件\u路径=%folder\u path%\path\to\some\FILE) 也就是说,我倾向于使用如下路径:C:\path\to\folder\\path\to\some\file.txt

我已经养成习惯,总是在文件夹路径的末尾放一个尾随斜杠,这似乎是惯例(例如,Visual Studio宏,如$(ProjectDir)总是有一个尾随斜杠)。此外,当我将相对路径附加到现有文件夹路径的末尾时,我总是放一个前导斜杠,以防传递给我的文件夹路径没有尾随斜杠(例如,Windows批处理:设置完整\u文件\u路径=%folder\u path%\path\to\some\FILE)

也就是说,我倾向于使用如下路径:C:\path\to\folder\\path\to\some\file.txt(注意一行中的两个反斜杠)。此外,由于我使用的是dev\src dev\include和dev\script文件夹结构(其中.vcxproj文件和类似文件位于脚本文件夹中),因此我的大多数路径都会在某些宏(如$(ProjectDir)(例如include dir=$(ProjectDir)\..\include\)的末尾附加一个相对路径,其级别为

在以下代码中,somePath02Uri和somePath03Uri返回(我认为是)不正确的结果:

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间DotNet45SystemUriTest
{
班级计划
{
静态void Main(字符串[]参数)
{
WriteLine(“我们现在将测试System.Uri构造函数:\n”);
//Console.WriteLine的输出位于同一行的注释中
String somePath01=“C:\\some\\common\\..\\include\\”;
Console.WriteLine(“somePath01=“+somePath01”);//somePath01=C:\some\common\..\include\
Uri somePath01Uri=新Uri(somePath01);
Console.WriteLine(“somePath01Uri=“+somePath01Uri.ToString());//somePath01Uri=file:///C:/some/include/
Console.WriteLine();
String somePath02=“C:\\some\\common\\\\\\\\\\include\\”;
Console.WriteLine(“somePath02=“+somePath02”);//somePath02=C:\some\common\\\..\include\
Uri somePath02Uri=新Uri(somePath02);
Console.WriteLine(“somePath02Uri=“+somePath02Uri.ToString());//somePath02Uri=file:///C:/some/common/include/
Console.WriteLine();
String somePath03=“C:\\some\\common\\include\\”;
Console.WriteLine(“somePath03=“+somePath03”);//somePath03=C:\some\common\\\\\…\include\
Uri somePath03Uri=新Uri(somePath03);
Console.WriteLine(“somePath03Uri=“+somePath03Uri.ToString());//somePath03Uri=file:///C:/some/common//include/
Console.WriteLine();
}
}
}
为什么System.Uri将一行中的两个斜杠解释为文件夹

差点忘了:如果遇到这种情况,一个快速而肮脏的解决方案是在创建Uri对象之前从字符串中删除一行中的两个反斜杠。为此,我添加了
。替换(“\\\”,“\\”)

String somePath02=“C:\\some\\common\\\\\\\\include\\”;
Console.WriteLine(“somePath02=“+somePath02”);//somePath02=C:\some\common\\\..\include\
Uri somePath02Uri=新Uri(somePath02.Replace(“\\\\”,“\\”);
Console.WriteLine(“somePath02Uri=“+somePath02Uri.ToString());//somePath02Uri=file:///C:/some/include/

用于不转义的两个斜杠

例如,尝试以下方法:

string path=“c:\test\html”

当你编译这段代码时,你会得到一个错误“无法识别的转义序列”

但是如果您添加了一个额外的斜杠,您会告诉编译器没有转义,字符串应该按原样解析

string path=“c:\\test\\html”

另一种用于不转义的有趣方法是:

字符串路径=@“c:\test\html”


它与URI无关,只是在c#字符串中转义控制字符。您也可以使用@符号,例如
String somePath02=@“C:\some\common\\\\..\include\”
String somePath02=“C:\\some\\common\\\\\\\\\\\\\include\\”相同
符号@告诉编译器以下字符串不包含控制字符。@Ron Beyer:嗨,Ron,我不确定您是否有机会查看Uri的输出。如果我提供的路径是
C:\topLevelFolder1\..\topLevelFolder2
,那么我希望解析的绝对路径是
C:\topLevelFolder2
。同样,如果我提供的路径是
C:\topLevelFolder1\\..\topLevelFolder2
,我仍然希望解析的绝对路径是
C:\topLevelFolder2
。您是否尝试将UriKind指定为相对路径?我认为它默认为绝对。。。至于原因,系统实际上允许空白文件夹名称,因此它将两个斜杠解释为空白命名文件夹。有关如何创建它们,请参见此:请查看实现,而不是连接我们自己的路径。这将消除您获得的双\\值。@RonBeyer在链接中创建的文件夹名与没有名称完全不同。windows系统根本不支持完全空白的文件夹名称。看起来可能不是这样,但有一个实际字符正被用作该文件夹的名称。很抱歉,您的问题被问错了,因为Uri()没有将两个斜杠解释为文件夹。就像@Ron Beyer所说的,它与Uri()无关,它是一个转义/编译器的东西。从我看到的情况来看,您希望Uri能够解释像“C:\topLevelFolder1\topLevelFolder2”这样的路径……在这种情况下,您应该要求Microsoft添加此新功能。甚至Ron Beyer也确认“系统实际上允许使用空文件夹名”,这对我来说意味着Uri()实际上是,将两个斜杠解释为文件夹(或者至少Uri假装位于这两个斜杠之间的空字符串被解释为文件夹)。