【问题标题】:Why is this function returning nothing, although there is a match?为什么这个函数没有返回任何东西,尽管有匹配?
【发布时间】:2014-03-08 02:40:25
【问题描述】:

我正在调用这个(Compact Framework - 此代码在 Windows CE 手持设备上运行)方法:

public static List<string> GetXMLFiles(string fileType, string startingDir)
{
    const string EXTENSION = ".XML";
    string dirName = startingDir; 
    var fileNames = new List<String>();
    try
    {
        foreach (string f in Directory.GetFiles(dirName))
        {
            string ext = Path.GetExtension(f).ToUpper();
            string fileNameOnly = Path.GetFileNameWithoutExtension(f);
            if ((ext.Equals(EXTENSION, StringComparison.OrdinalIgnoreCase)) && (fileNameOnly.Contains(fileType)))
            {
                fileNames.Add(f);
            }
        }
        foreach (string d in Directory.GetDirectories(dirName))
        {
            GetXMLFiles(fileType, d);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    return fileNames;
}

...像这样:

List<String> XMLFiles = CCRUtils.GetXMLFiles(fileType, "\\");
MessageBox.Show(XMLFiles.Count.ToString());

...但它什么也没返回(MessageBox 显示“0”),即使有一个文件与 fileType 匹配并且具有 .xml 扩展名。

是不是因为我的 GetXMLFiles() 方法有问题?根据一只猫here,我的方法被搞砸了,我应该更频繁地添加到字符串(文件名)的通用列表中。

如果他是对的,但我不明白,因为在我看来,这就是该方法的工作方式:

(a) The first foreach loop looks at files below the root; if a match is found, it's added to the generic list of string
(b) The second foreach loop makes a recursive call to its method, once for every subdirectory on the device; step "a" occurs again for that directory, adding any matches to the generic list of string.

通过这种方式,搜索所有目录,并将找到的任何匹配项添加到字符串(文件名)的通用列表中。

在第二个 foreach 循环运行其课程/处理所有目录后,控制权落到最后一行代码,它将文件名返回给调用者。

所以,根据我的理解,我应该得到匹配,但我什么也没得到。

如果我错了而 Alan 是对的,我应该在哪里添加对 add 的额外调用/应该如何重做这个方法?

更新

这样称呼它:

List<String> XMLFiles = CCRUtils.GetXMLFiles(fileType, "\\");

...不起作用,但这样可以:

List<String> XMLFiles = CCRUtils.GetXMLFiles(fileType, @"\");

【问题讨论】:

    标签: c# algorithm recursion foreach compact-framework


    【解决方案1】:

    在您的递归中,您会丢失在子目录中找到的文件。以这种方式捕获返回文件名:

    foreach (string d in Directory.GetDirectories(dirName))
    {
        fileNames.AddRange(GetXMLFiles(fileType, d));
    }
    

    发生了什么是var fileNames = new List&lt;String&gt;(); 这一行创建了一个名为fileNames 的局部变量。你可能会想,因为你的方法是静态的,所以方法里面的变量是静态的。不是这种情况。因此,每次调用 GetXMLFiles 时,都会为每次调用创建此变量的副本。

    由于fileNamesGetXMLFiles 的每次调用都是本地的,因此您需要将它找到的所有文件名返回给调用者,并且调用者需要将它们添加到它的本地集合中。

    【讨论】:

    • 我仍然不明白为什么会发生这种情况,但如果它有效,那也没关系;你的意思是在递归调用上面加上这行代码?
    • @B.ClayShannon,将循环中的行替换为我的行。
    • 我明白了,谢谢。我想已经很晚了(无论如何,这是我的借口)。
    • @B.ClayShannon 我昨天试图告诉你!你说你不明白为什么会这样。考虑一下,如果您在循环中删除了对 GetXMLFiles 的调用会怎样?您会期望它不会在子目录中找到任何文件,因为循环什么都不做?好吧,GetXMLFiles 返回一个文件列表,对吧?您之前甚至没有使用过返回的列表,因此它什么也不做。您必须使用 AddRange 将其附加到结果中才能递归地构建整个文件列表。
    • 我会相信你的话,但要真正理解它,我必须从视觉上看到它——用箭头之类的。试图在我的脑海中逐步解决它,我的大脑崩溃了,我比以往任何时候都更加困惑。
    猜你喜欢
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    相关资源
    最近更新 更多