【问题标题】:DirectoryInfo.ToString works differently on Parent directories?DirectoryInfo.ToString 在父目录上的工作方式不同?
【发布时间】:2017-12-24 09:18:17
【问题描述】:

为什么DirectoryInfo.ToString 有时返回FullName(路径)而有时只返回目录-Name?我只是注意到它,因为我试图在这里将父目录名称与目录名称连接起来:

DirectoryInfo dir = new DirectoryInfo(@"C:\Users\Administrator\Desktop\unpack\folder1");
DirectoryInfo parentDir = dir.Parent;
var dirAndParent = $"{parentDir}{Path.DirectorySeparatorChar}{dir.Name}";

令我惊讶的是,这有效并返回了所需的部分unpack\folder1。 我想我需要parentDir.Name 而不是parentDir,类似于dir.Name。如果我从dir.Name 中删除Name,我将获得目录的完整路径。但是父 DirectoryInfo 实例只返回 Name

它在哪里记录,DirectoryInfo 实例之间有什么区别?

Console.WriteLine("dir.ToString: \t\t" + dir.ToString());
Console.WriteLine("parentDir.ToString: \t" + parentDir.ToString());

将为dir 输出FullName(路径),为parentDir 输出Name

dir.ToString:           C:\Users\Administrator\Desktop\unpack\folder1
parentDir.ToString:     unpack

parentDir.FullName 还返回完整路径:C:\Users\Administrator\Desktop\unpack


也许是一个错误,但肯定是缺少文档。 教训很清楚:如果DirectoryInfo 实例是通过DirectoryInfo.Parent 初始化的,则永远不要使用DirectoryInfo.ToString 或将实例传递给String.Format(或字符串插值)等隐式使用ToString 的方法。由于您通常不知道它是如何初始化的,因此通常最好避免使用DirectoryInfo.ToString。这个错误(不一致的、不透明的行为)将来可能会被修复,这会破坏代码。

【问题讨论】:

  • 不是一个答案,但为什么不直接使用 Path.Combine 并直接提供名称而不是使用路径分隔符字符进行字符串连接?我认为当 parent 是驱动器根时,您可能会得到甚至不同的结果——我可能记错了,但我认为 new DirectoryInfo("c:").ToString() 已经包含路径分隔符。尽管我承认您遇到的结果很奇怪/很有趣,但我期待有人回答。如果您在父级上执行Refresh(),输出会改变吗?可能与.Net 所做的文件系统条目/名称的缓存和规范化有关。
  • @pinkfloydx33:你是对的,在这种情况下Path.Combine(parentDir.Name, dir.Name) 会更好,也可以避免这个问题,因为你不能将DirectoryInfo 实例传递给Path.Combine,你必须是明确的。但它并没有解释或解决这个问题。 DirectoryInfo.ToString 坏了

标签: c# .net io directoryinfo


【解决方案1】:

查看来自MSDN 的 ToString 定义,似乎对该方法的调用返回了传入的原始路径。

在您的通话中

DirectoryInfo dir = new DirectoryInfo(@"C:\Users\Administrator\Desktop\unpack\folder1");

您传入了目录的完整路径。通过使用属性访问父节点,您没有显式调用具有完整路径的构造函数。在内部它可能使用了相对路径。

【讨论】:

    【解决方案2】:

    我查看了 Microsoft 提供的 DirectoryInfo 源代码,您可以轻松重现此行为。当您调用 Parent 属性时,他们正在使用 Internal constructor internal DirectoryInfo(String fullPath, bool junk)

    以下内容无需致电Parent即可重现您的问题:

    var dirInfoUsingPublicConstructor = new DirectoryInfo(@"C:\Test");
    Console.WriteLine(dirInfoUsingPublicConstructor.ToString());
    
    var ctor = typeof(DirectoryInfo).GetConstructors(BindingFlags.NonPublic 
                                                    | BindingFlags.Instance).First();
    var dirInfoUsingInternalConstructor = 
                ctor.Invoke(new object[] { @"C:\Test", false }) as DirectoryInfo;
    Console.WriteLine(dirInfoUsingInternalConstructor.ToString());
    

    结果:

    C:\Test
    Test
    

    在内部,该构造函数使用Path.GetFileName 来获取结果。仅返回文件夹名称。我不知道实现细节中这种区别背后的原因。这可能是一个错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-08
      • 2018-12-11
      • 2014-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多