Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 抽象索引遍历的优雅方法_C#_Linq - Fatal编程技术网

C# 抽象索引遍历的优雅方法

C# 抽象索引遍历的优雅方法,c#,linq,C#,Linq,我有两种方法做完全相同的事情,除了一种方法检查从当前向前的一系列指数,另一种方法检查从当前向后的一系列指数。我已经对功能进行了抽象,这样公共代码就在一个方法中,它只需要一个IEnumerable作为参数,就可以知道要迭代的索引范围。现在,我的两种方法简化为: private List<Thingy> GetForwardThingies() { var indices = new List<int>(); for (var i = _project.Cur

我有两种方法做完全相同的事情,除了一种方法检查从当前向前的一系列指数,另一种方法检查从当前向后的一系列指数。我已经对功能进行了抽象,这样公共代码就在一个方法中,它只需要一个IEnumerable作为参数,就可以知道要迭代的索引范围。现在,我的两种方法简化为:

private List<Thingy> GetForwardThingies()
{
    var indices = new List<int>();
    for (var i = _project.Current; i < _project.GetLimit(); i++)
        indices.Add(i);
    return GetThingiesByIteratingOverIndices(indices);
}

private List<Thingy> GetBackwardsThingies()
{
    var indices = new List<int>();
    for (var i = _project.Current; i >= 0; i--)
        indices.Add(i);
    return GetThingiesByIteratingOverIndices(indices);
}
是否有一种更优雅的方式,或许可以使用LINQ来封装这个抽象?GetThingiesByAteratingVeriences非常快,而且速度并不关键,因为它将在不超过几十个索引上运行,因此效率不是主要关注点。我在想,也许在C8.0中的新系统。范围的东西会有所帮助,但遗憾的是,它不允许一种方式来表达一个向后的范围。而且,是的,顺序很重要,所以我不能从0到Current来得到向后的东西

新信息 好的,我试图保持简单,但我想我需要给出GetThingiesByAteratingVeriences的真正实现:

当然,迭代是热切的。ToList是alltogether可选的;您始终可以返回IEnumerable并将执行延迟到调用方决定执行的任何时候

在这两种情况下,您的代码可能效率更高。跳过和反转可能会有点昂贵,但如果迭代项的数量很小,那么问题就不会像您在问题中正确假设的那样严重

当然,迭代是热切的。ToList是alltogether可选的;您始终可以返回IEnumerable并将执行延迟到调用方决定执行的任何时候


在这两种情况下,您的代码可能更高效跳过和反向可能会有点昂贵,但如果迭代项的数量很小,则不会像您在问题中正确假设的那样成为一个问题。

[0..MaxValue]。反向?如果不是注释,我会尝试将其标记为答案,因为它看起来很优雅。但是,由于新的System.Index和System.Range类型没有也显然不会包含在.net Framework中,因此新的范围语法对我来说甚至不可用。也许其他来找她的人会发现这很有用。[0..MaxValue]。相反?如果这不是一条评论,我很想把它作为答案,因为它看起来很优雅。但是,由于新的System.Index和System.Range类型没有也显然不会包含在.net Framework中,因此新的范围语法对我来说甚至不可用。也许其他来找她的人,他们的目标是.net Core 3.0,他们会发现这很有用。没有一个对象可以封装我列举的东西。在我最初的描述中,我几乎是这样说的——我想我应该这样做。这就是我通过IEnumerable考试的原因。GetThingiesByAteratingVeriences多次使用每个索引来访问检索状态信息的各种支持方法。@TomBogle Ok,这是相关信息。尽管如此,您仍然可以应用相同的解决方案来检索索引,然后,或者像现在一样使用结果枚举,或者使用投影。如果这种方法可用,请选择I=>GetThingyByIndexi。我在上面添加了新的信息,我认为这些信息说明了为什么简单的投影不起作用。没有一个对象可以封装我列举的内容。在我最初的描述中,我几乎是这样说的——我想我应该这样做。这就是我通过IEnumerable考试的原因。GetThingiesByAteratingVeriences多次使用每个索引来访问检索状态信息的各种支持方法。@TomBogle Ok,这是相关信息。尽管如此,您仍然可以应用相同的解决方案来检索索引,然后,或者像现在一样使用结果枚举,或者使用投影。如果这种方法可用,请选择I=>GetThingyByIndexi。我在上面添加了新信息,我认为这说明了为什么简单投影不起作用。
private List<ScriptLine> GetRecordableBlocksUpThroughHole(IEnumerable<int> indices)
{
    var bookInfo = _project.SelectedBook;
    var chapter = _project.SelectedChapterInfo.ChapterNumber1Based;
    var lines = new List<ScriptLine>();
    foreach (var i in indices)
    {
        if (!_project.IsLineCurrentlyRecordable(bookInfo.BookNumber, chapter, i))
            break;
        var block = bookInfo.ScriptProvider.GetBlock(bookInfo.BookNumber, chapter, i);
        lines.Add(block);
        if (!block.Skipped && !ClipRepository.GetHaveClip(_project.Name, bookInfo.Name, chapter, i, _project.ScriptProvider))
            return lines;
    }
    return new List<ScriptLine>();
}
private List<Thingy> GetForwardThingies() =>
    _whateverEnumerableYouAreIterating.Skip(_project.Current)
                                      .ToList();

private List<Thingy> GetBackwardsThingies() =>
    _whateverEnumerableYouAreIterating.Take(_project.Current - 1)
                                      .Reverse()
                                      .ToList();