这是否可以被重构为漂亮的LINQ?[英] Can this be refactored into nicey nice LINQ?

本文是小编为大家收集整理的关于这是否可以被重构为漂亮的LINQ?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有一个 Breadcrumb 类型的 IList,它只是一个具有 NavigationTitle、NavigationUrl 和 IsCurrent 属性的轻量级类.它缓存在网络服务器上.我有一个方法可以构建当前的面包屑跟踪,直到第一个将 IsCurrent 设置为 true 的面包屑......使用下面的代码.它非常丑陋,绝对是一个快速的垃圾袋威利解决方案,但我很好奇,这可以很容易地重构为 LINQ 吗?

IList<Breadcrumb> crumbs = new List<Breadcrumb>();
bool foundCurrent = false;
for (int a = 0; a < cachedCrumbs.Count; a++)
{
    crumbs.Add(crumbs[a]);
    if (foundCurrent)
    {
      break;
    }
    foundCurrent = (crumbs[a + 1] != null && ((Breadcrumb)crumbs[a + 1]).IsCurrent);
}

推荐答案

我按我的想法输入这个,以便它显示一个思路以及一个答案.

  • 您的来源只是缓存的Crumbs
  • 您想添加第一个 设置了 IsCurrent 的面包屑,但之后没有任何内容
  • TakeWhile 听起来像是要走的路,但要获得"以前的值有 IsCurrent"有点痛苦
  • 我们可以使用闭包来有效地保留一个变量来确定最后一个值是否设置了 IsCurrent
  • 我们可以做一个有点"无操作"的选择,以将 TakeWhile 与是否继续进行的工作区分开来

所以,我们最终得到:

bool foundCurrent = false;

var crumbs = cachedCrumbs.TakeWhile(crumb => !foundCurrent)
                         .Select(crumb => { 
                                 foundCurrent = crumb == null || !crumb.IsCurrent; 
                                 return crumb; });

我还没有尝试过,但我认为它应该可以工作......不过可能有更简单的方法.

编辑:我认为在这种情况下,实际上一个直接的 foreach 循环 更简单.话虽如此,您可以编写另一个类似于 TakeWhile 的扩展方法,除了它也返回导致条件失败的元素.那么它会很简单:

var crumbs = cachedCrumbs.NewMethod(crumb => crumb == null || !crumb.IsCurrent);

(目前我想不出一个合适的方法名称,因此 NewMethod !)

本文地址:https://www.itbaoku.cn/post/1557091.html

问题描述

I have an IList of type Breadcrumb which is just a lightweight class that has NavigationTitle, NavigationUrl and IsCurrent properties. It is cached on the webserver. I have a method that builds out the current breadcrumb trail up until the first Breadcrumb that has IsCurrent set to true... using the code below. Its very ugly and definitely a quick dirtbag willie solution, but I was curious, can this be easily refactored into LINQ?

IList<Breadcrumb> crumbs = new List<Breadcrumb>();
bool foundCurrent = false;
for (int a = 0; a < cachedCrumbs.Count; a++)
{
    crumbs.Add(crumbs[a]);
    if (foundCurrent)
    {
      break;
    }
    foundCurrent = (crumbs[a + 1] != null && ((Breadcrumb)crumbs[a + 1]).IsCurrent);
}

推荐答案

I'm typing this as I think, so that it shows a train of thought as well as just an answer.

  • Your source is just cachedCrumbs
  • You want to add the first crumb which does have IsCurrent set, but nothing afterwards
  • TakeWhile sounds like the way to go, but getting the "previous value had IsCurrent" is a bit of a pain
  • We can use a closure to effectively keep a variable determining whether the last value had IsCurrent set
  • We can do a somewhat "no-op" select to keep the TakeWhile separate from the working out of whether to keep going

So, we end up with:

bool foundCurrent = false;

var crumbs = cachedCrumbs.TakeWhile(crumb => !foundCurrent)
                         .Select(crumb => { 
                                 foundCurrent = crumb == null || !crumb.IsCurrent; 
                                 return crumb; });

I haven't tried this, but I think it should work... there might be a simpler way though.

EDIT: I'd argue that actually a straight foreach loop is simpler in this case. Having said that, you could write another extension method which acted like TakeWhile except it also returned the element which caused the condition to fail. Then it would be as simple as:

var crumbs = cachedCrumbs.NewMethod(crumb => crumb == null || !crumb.IsCurrent);

(I can't think of a decent name for the method at the moment, hence NewMethod !)