13

我被该方法的一个非常奇怪的行为击中了脸System.IO.Directory.GetParent

string path1 = @"C:\foo\bar";
DirectoryInfo parent1 = Directory.GetParent(path1);
Console.WriteLine (parent1.FullName); // Prints C:\foo, as expected

// Notice the extra backslash. It should still refer to the same location, right ?
string path2 = @"C:\foo\bar\";
DirectoryInfo parent2 = Directory.GetParent(path2);
Console.WriteLine (parent2.FullName); // Prints C:\foo\bar !!!

我会认为这是一个错误,但这种方法从 1.0 开始就存在,所以我想它现在已经被检测到了。另一方面,如果它是按照设计的,我想不出对这种设计的合理解释……

你怎么看 ?这是一个错误吗?如果不是,你如何解释这种行为?

4

3 回答 3

11

一些谷歌搜索揭示了一些想法

DirectoryInfo di = new DirectoryInfo(@"C:\parent\child");
Console.WriteLine(di.Parent.FullName);

DirectoryInfo di = new DirectoryInfo(@"C:\parent\child\");
Console.WriteLine(di.Parent.FullName);

两者都返回 "C:\parent"

我只能假设Directory.GetParent(...)不能假设这C:\parent\child是一个目录而不是没有文件扩展名的文件。DirectoryInfo可以,因为您正在以这种方式构造对象。


我个人认为,当有反斜杠时,字符串被视为目录内“空文件”的路径(即没有名称和扩展名的文件)。显然,那些可以存在(应该有一个链接,但由于某种原因我找不到任何东西)。

尝试FileInfopath2. 您会看到它的构造正确,String.Empty名称和扩展名为,不存在,C:\foo\barDirectoryName. 鉴于此,这种情况是有道理的:这个“空文件”的父对象确实是C:\foo\bar.

于 2010-10-18T23:24:50.763 回答
3

我同意GSerg。只是为了增加一些额外的火力,我将添加以下使用 Reflector 获得的代码片段。

Directory.GetParent 函数基本上只是调用 Path.GetDirectoryName 函数:

[SecuritySafeCritical]
public static DirectoryInfo GetParent(string path)
{
    if (path == null)
    {
        throw new ArgumentNullException("path");
    }
    if (path.Length == 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), "path");
    }
    string directoryName = Path.GetDirectoryName(Path.GetFullPathInternal(path));
    if (directoryName == null)
    {
        return null;
    }
    return new DirectoryInfo(directoryName);
}

DirectoryInfo 的 Parent 属性基本上去掉了一个斜杠,然后调用 Path.GetDirectoryName:

public DirectoryInfo Parent
{
    [SecuritySafeCritical]
    get
    {
        string fullPath = base.FullPath;
        if ((fullPath.Length > 3) && fullPath.EndsWith(Path.DirectorySeparatorChar))
        {
            fullPath = base.FullPath.Substring(0, base.FullPath.Length - 1);
        }
        string directoryName = Path.GetDirectoryName(fullPath);
        if (directoryName == null)
        {
            return null;
        }
        DirectoryInfo info = new DirectoryInfo(directoryName, false);
        new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, info.demandDir, false, false).Demand();
        return info;
    }
}
于 2010-10-18T23:52:13.373 回答
1

这很有趣。首先,当我读到这篇文章时,我很确定这将是一个错误,但是当我想得更久时,我得出的结论是,可能的意图是路径不应该是目录,而是一个完整或相对路径文件。所以

c:\somenonexistingpath\to\a\directory\

被解释为在 ...\directory 中没有名称的文件的路径。这有点傻,但如果我们假设微软的程序员期望文件的完整路径,那么不涉及这种情况是有意义的。

编辑:

注意

c:\dir\makefile -> c:\dir

c:\dir\build.msbuild -> c:\dir

按预期给父母。

于 2010-10-18T23:44:20.017 回答