Метод расширения ForEach для ListItemCollection - PullRequest
6 голосов
/ 29 апреля 2011

Я реализовал 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 может быть только один элемент, соответствующий этому требованию, но цикл все равно завершаетсяКакой самый уродливый способ решить эту проблему?

Спасибо.

Ответы [ 4 ]

5 голосов
/ 29 апреля 2011

Вы можете взять Func<ListItem, bool> вместо Action<ListItem> и разорвать цикл, если он вернет 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 голосов
/ 29 апреля 2011
public static void ForEach(this ListItemCollection collection, Action<ListItem> act )
{
    foreach (ListItem item in collection)
    {
        act(item);
        if(condition) break;
    }
}
1 голос
/ 29 апреля 2011

Ваши требования не ясны на 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;
           }
        }
    }
    
1 голос
/ 29 апреля 2011

Сначала сделайте это:

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

чтобы получить общую коллекцию.

Тогда Использование может свернуть ваш собственный, общий метод расширения :

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...