C# 好的lambda表达式或更好的方法来减少每个循环

C# 好的lambda表达式或更好的方法来减少每个循环,c#,.net,C#,.net,我想获取根文件夹的子文件夹。我可以通过下面的代码得到它。 但是有一个问题,当子文件夹中有一个子文件夹时,我为每个循环写了一秒钟。但是如果第二个子文件夹下有一个子文件夹呢。 所以每个循环都有一个infinte,所以我必须克服它。 任何帮助都是值得的。提前谢谢 foreach (Folder.Folder folder in FolderService.Instance.GetSubFolders(userContext, folderID)) {

我想获取根文件夹的子文件夹。我可以通过下面的代码得到它。 但是有一个问题,当子文件夹中有一个子文件夹时,我为每个循环写了一秒钟。但是如果第二个子文件夹下有一个子文件夹呢。 所以每个循环都有一个infinte,所以我必须克服它。 任何帮助都是值得的。提前谢谢

foreach (Folder.Folder folder in FolderService.Instance.GetSubFolders(userContext, folderID))
            {
                folderById.Add(folder.FolderID, folder);
                foreach (Folder.Folder sfolder in FolderService.Instance.GetSubFolders(userContext, folder.FolderID))
                {
                    folderById.Add(sfolder.FolderID, sfolder);
                }
            }

递归的最佳位置:

foreach (Folder.Folder folder in FolderService.Instance.GetSubFolders(userContext, folderID))
            {
                folderById.Add(folder.FolderID, folder);
                foreach (Folder.Folder sfolder in FolderService.Instance.GetSubFolders(userContext, folder.FolderID))
                {
                    folderById.Add(sfolder.FolderID, sfolder);
                }
            }
... TraverseFolder(rootFolderID, userContext)
{
    var folderById = new ...;
    TraverseFolder(folderById, rootFolderID, userContext);

    return folderById;
}

void TraverseFolder(folderById, folderID, userContext)
{
    var folders = FolderService.Instance.GetSubFolders(userContext, folderID);
    foreach(var folder in folders)
    {
        folderById.Add(folder.FolderID, folder);
        TraverseFolder(folder.FolderID);
    }
}

从理论上讲,可以有,但它们太复杂了。

这里有两个使用labdas的附加示例。第一个使用本地声明的函数递归项(本例中为DirectoryInfos),第二个使用实例方法

foreach (Folder.Folder folder in FolderService.Instance.GetSubFolders(userContext, folderID))
            {
                folderById.Add(folder.FolderID, folder);
                foreach (Folder.Folder sfolder in FolderService.Instance.GetSubFolders(userContext, folder.FolderID))
                {
                    folderById.Add(sfolder.FolderID, sfolder);
                }
            }
class Program
{
    static void Main(string[] args) {
        string path = @"d:\temp";

        Func<DirectoryInfo, IEnumerable<DirectoryInfo>> func = null;
        func = (folder) => {
            return new[] { folder }.Concat(folder.GetDirectories().SelectMany(x => func(x)));
        };

        IEnumerable<DirectoryInfo> dirs = (new DirectoryInfo(path)).GetDirectories().SelectMany(x => func(x));

        IEnumerable<DirectoryInfo> dirs2 = GetSubDirs(new DirectoryInfo(path));
    }

    public static IEnumerable<DirectoryInfo> GetSubDirs(DirectoryInfo dir) {
        yield return dir;
        foreach (var subDir in GetSubDirs(dir)) yield return subDir;
    }

    // method 2 even shorter
    public static IEnumerable<Directory> GetSubDirs2(DirectoryInfo dir) {
        return new[] { dir }.Concat(dir.GetDirectories().SelectMany(x => GetSubDirs2(x)));
    }
}
类程序
{
静态void Main(字符串[]参数){
字符串路径=@“d:\temp”;
Func Func=null;
func=(文件夹)=>{
返回新的[]{folder}.Concat(folder.GetDirectories().SelectMany(x=>func(x));
};
IEnumerable dirs=(new DirectoryInfo(path)).GetDirectories().SelectMany(x=>func(x));
IEnumerable dirs2=GetSubDirs(新目录信息(路径));
}
公共静态IEnumerable GetSubDirs(目录信息目录){
收益回报率;
foreach(GetSubDirs中的var subDir(dir))产生返回subDir;
}
//方法2甚至更短
公共静态IEnumerable GetSubders2(目录信息目录){
返回新的[]{dir}.Concat(dir.GetDirectories().SelectMany(x=>GetSubDirs2(x));
}
}

以下是一个示例,说明如何使用递归lambda表达式和LINQ中的
SelectMany
方法编写递归遍历:

foreach (Folder.Folder folder in FolderService.Instance.GetSubFolders(userContext, folderID))
            {
                folderById.Add(folder.FolderID, folder);
                foreach (Folder.Folder sfolder in FolderService.Instance.GetSubFolders(userContext, folder.FolderID))
                {
                    folderById.Add(sfolder.FolderID, sfolder);
                }
            }
Func<string, IEnumerable<string>> folders = null;
folders = s =>
  Directory.GetDirectories(s).SelectMany(dir =>
    Enumerable.Concat(new[] { dir }, folders(dir)));

foreach (var d in folders("C:\\Tomas\\Writing\\Academic"))
  Console.WriteLine(d);

代码使用类似于C#迭代器的序列表达式<代码>收益率对应于
收益率回报率
收益率
生成序列的所有元素(就像使用
foreach
对其进行迭代,并使用
生成返回
生成单个元素,但效率更高)。

字典不在字段级别,而不是通过递归调用传递,这有什么好的理由吗

foreach (Folder.Folder folder in FolderService.Instance.GetSubFolders(userContext, folderID))
            {
                folderById.Add(folder.FolderID, folder);
                foreach (Folder.Folder sfolder in FolderService.Instance.GetSubFolders(userContext, folder.FolderID))
                {
                    folderById.Add(sfolder.FolderID, sfolder);
                }
            }
Dictionary<string, int> folderById = new Dictionary<string,int>();
public void Start()
{
    // code for initial context + folder id
    RecurseFolders(userContext, folderId);
}

public void RecurseFolders(string userContext, int folderId)
{
    foreach (Folder.Folder folder in FolderService.Instance.GetSubFolders(userContext, folderID)) {
        folderById.Add(folder.FolderID, folder);
        RecurseFolders(userContext, folder.folderId);
    }
}
Dictionary folderById=new Dictionary();
公开作废开始()
{
//初始上下文+文件夹id的代码
递归文件夹(userContext,folderId);
}
公共void递归文件夹(字符串userContext,int folderId)
{
foreach(FolderService.Instance.GetSubFolders中的Folder.Folder文件夹(userContext,folderID)){
添加(folder.FolderID,folder);
递归文件夹(userContext,folder.folderId);
}
}

我完成了。这是密码

foreach (Folder.Folder folder in FolderService.Instance.GetSubFolders(userContext, folderID))
            {
                folderById.Add(folder.FolderID, folder);
                foreach (Folder.Folder sfolder in FolderService.Instance.GetSubFolders(userContext, folder.FolderID))
                {
                    folderById.Add(sfolder.FolderID, sfolder);
                }
            }
 private List<Folder.Folder> GetAllF(AbstractUserContext userContext, string folderID)
    {
        List<Folder.Folder> listFold = new List<Folder.Folder>();
        foreach (Folder.Folder folder in FolderService.Instance.GetSubFolders(userContext, folderID))
        {
            listFold.Add(folder);
            listFold.AddRange(GetAllF(userContext,folder.FolderID));
        }
        return listFold;
    }
私有列表GetAllF(AbstractUserContext用户上下文,字符串folderID) { List listFold=新列表(); foreach(FolderService.Instance.GetSubFolders中的Folder.Folder文件夹(userContext,folderID)) { 添加(文件夹); AddRange(GetAllF(userContext,folder.FolderID)); } 返回列表折叠; }
Hi anton我完全搞不清楚这两种方法是不是分开的,这样就不用复制/合并字典/列表了。请检查我的相关问题-一些答案可能对您有用: