【问题标题】:ForEach Extension Method for ListItemCollectionListItemCollection 的 ForEach 扩展方法
【发布时间】:2011-04-29 10:41:36
【问题描述】:

我实现了一个 ExtensionMethod,它基本上作为 ForEach-Loop 工作,我的实现如下所示:

public static void ForEach(this ListItemCollection collection, Action<ListItem> act )
{
    foreach (ListItem item in collection)
        act(item);
}

但是,我希望在第一次满足特定条件后停止循环的方法。

这是我目前的使用方式:

ddlProcesses.Items.ForEach(item => item.Selected = item.Value == Request["Process"]?true:false);

这样做的问题是 DropDownList 中只能有一项符合此要求,但循环无论如何都已完成,解决此问题的最不难看的方法是什么?

谢谢。

【问题讨论】:

  • 如果您不尝试 ddlProcesses.Items.FindByValue(Request["Process"]).Selected = true; 将是最简单的事情
  • @V4Vendetta:使用波浪号突出显示syntax in comments
  • @abatishchev 取消选择所有项目?
  • @V4Vendetta:抱歉,在 OP 的问题中没有这样的任务。但事实上,我猜他以后会需要这个。但一切都取决于他:)
  • @abatishchev 也许他有,也可能没有 ClearSelection() 可以解决问题

标签: c# .net linq extension-methods listitem


【解决方案1】:

您可以使用Func&lt;ListItem, bool&gt; 而不是Action&lt;ListItem&gt;,如果它返回true,则中断循环:

public static void ForEach(this ListItemCollection collection,
    Func<ListItem, bool> func)
{
    foreach (ListItem item in collection) {
        if (func(item)) {
            break;
        }
    }
}

你可以这样使用它:

ddlProcesses.Items.ForEach(
    item => item.Selected = (item.Value == Request["Process"]));

【讨论】:

    【解决方案2】:
    public static void ForEach(this ListItemCollection collection, Action<ListItem> act )
    {
        foreach (ListItem item in collection)
        {
            act(item);
            if(condition) break;
        }
    }
    

    【讨论】:

    • 条件从何而来?
    • @abatischev 这是来自 OP “我希望在第一次满足特定条件后停止循环的方法。”
    • @Peter OP 可以将他的条件放在那里......我只是想让他知道你可以通过休息来停止 foreach 循环;
    【解决方案3】:

    首先这样做:

    IEnumerable<ListItem> e = ddlProcesses.Items.OfType<ListItem>(); // or Cast<ListItem>()
    

    获取通用集合。

    然后use can roll your own, generic extension method:

    public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
    {
        foreach (T item in collection) action(item);
    }
    
    public static void ForEach<T>(this IEnumerable<T> collection, Func<T> func)
    {
        foreach (T item in collection) if (func(item)) return;
    }
    

    不管怎样,缓存查找结果:

    var process = Request["Process"];
    
    e.ForEach(i => i.Selected = i.Value == process);
    

    【讨论】:

    • e.ToList() 导致在迭代之前将整个列表复制到一个新的 List 实例中。这可能是不可取的。
    【解决方案4】:

    您的要求并非 100% 明确。您是否需要处理所有项目以将它们设置为 false,除了唯一符合条件的项目,还是只想找到具有正确条件的项目,或者您想应用一个函数直到满足条件?

    1. 仅在条件第一次匹配时才对项目执行操作

      public static void ApplyFirst(this ListItemCollection collection,
                            Action<ListItem> action, Func<ListItem, bool> predicate)
      {
          foreach (ListItem item in collection) 
          {
             if (predicate(item))
             {
                 action(item);
                 return;
             }
          }
      }
      
    2. 每次条件匹配时对项目执行操作

      public static void ApplyIf(this ListItemCollection collection,
                            Action<ListItem> action, Func<ListItem, bool> predicate)
      {
          foreach (ListItem item in collection) 
          {
             if (predicate(item))
             {
                 action(item);
             }
          }
      }
      
    3. 对所有项目做某事直到条件匹配

      public static void ApplyUntil(this ListItemCollection collection,
                            Action<ListItem> action, Func<ListItem, bool> predicate)
      {
          foreach (ListItem item in collection) 
          {
             action(item);
             if (predicate(item))
             {
                 return;
             }
          }
      }
      

    【讨论】:

      猜你喜欢
      • 2018-09-06
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-24
      • 1970-01-01
      相关资源
      最近更新 更多