【问题标题】:C# - retrieve file path from config file - @ doesn't do it's magicC# - 从配置文件中检索文件路径 - @ 不这样做很神奇
【发布时间】:2026-01-31 09:50:01
【问题描述】:

我目前正在开发一个 Web 服务,它检索 XML 消息,将其归档,然后进一步处理它。存档文件夹是从 Web.config 中读取的。这就是归档方法的样子

private void Archive(System.Xml.XmlDocument xmlDocument)
{
    try
    {
        string directory = System.Configuration.ConfigurationManager.AppSettings.Get("ArchivePath");

        ParseMessage(xmlDocument);

        directory = string.Format(@"{0}\{1}\{2}", directory, _senderService, DateTime.Now.ToString("MMMyyyy"));
        System.IO.Directory.CreateDirectory(directory);

        string Id = _messageID;
        string senderService = _senderService;

        xmlDocument.Save(directory + @"\" + DateTime.Now.ToString("yyyyMMdd_") + Id + "_" + System.Guid.NewGuid().ToString().Substring(0, 13) + ".xml");
    }

我检索的路径结构是 C:\Program Files\Subfolder\Subfolder。在开发、QA、UAT 和 PRD 环境中一切正常。但是在另一台机器上,我现在需要安装 Web 服务(很遗憾,我无法调试),目录字符串是“C:Files”。 只是为了确保我仔细检查了不同机器上的 .NET 版本(我认为可能在字符串之前使用 @ 取决于版本);所有机器都使用 2.0.50727。

有人知道这个问题吗?

提前致谢!

编辑:我在目录变量之前看到 @ 对我提出的问题造成了一些混淆。这不是关于那个@(事实上,它不应该在那里。我已经删除了它)。

我的问题(改述)是: 当您在带引号的字符串之前放置 @ 时,例如 @"c:\folder\subfolder",它可以确保反斜杠不会被解释为转义字符,对吗?它在一台机器上工作但在另一台机器上不工作的原因可能是什么? (我确实同意顺便说一下使用 Path.Combine 的答案。我只是好奇是什么导致了这种不一致的行为)

【问题讨论】:

  • 我确信字符串上的 @ 前缀是由 C# 编译器而不是运行时处理的。另外,在构造路径字符串时应该使用System.IO.Path.Combine
  • 使用 @ 为变量添加前缀仅允许您使用保留关键字(@return、@break 等)创建变量名称。不要与用于前缀字符串文字的 @ 混淆。

标签: c# path backslash


【解决方案1】:

您可以尝试使用Path.Combine() 而不是 String.Format()。好example is here

【讨论】:

    【解决方案2】:

    当从配置文件中提取一个值时,它会自动正确转义。目录变量名称上的“@”符号并未将其设置为“显式” - 它告诉编译器它是一个命名参数。例如:

    public void (string[] args)
    {
       int length = args.Length;
       length = @args.Length; // Same thing!
    }
    

    变量名上的“@”运算符意味着不将该符号视为保留字。它允许您使用与关键字同名的变量名称:

    public static void Foo(object @class)
    {
         //@class exists here, even though class is a reserved keyword!
    } 
    

    此外,如果它得到的值是“C:Files”,那么这是无效的,因为它缺少一个“\”。 'C:\Files' 将是有效的。

    【讨论】:

    • 它缺少多个“\”。值 'C:\Program Files\subfolder\subfolder' 减少为 'C:Files'。即省略前面带有“\”的每个单词:“\Program”和所有子文件夹“\subfolder”。
    【解决方案3】:

    使用 Path.Combine(),例如:

    strFilename = CombinePaths(directory, _senderService) + DateTime.Now.ToString("MMMyyyy");
    

    【讨论】:

      【解决方案4】:

      根据您的问题,我认为您已经处理过:

      @directory
      

      好像它执行的功能一样:

      @"c:\myfolder\"
      

      不同之处在于第一个示例允许您使用保留字作为变量名,例如@class(不要养成使用它的习惯),第二个示例允许字符串包含非转义字符,例如.

      【讨论】: