Факторинг обработки скелета (C #) - PullRequest
2 голосов
/ 14 декабря 2010

Существует ли языковая конструкция в C #, которая позволяет абстрагировать циклическую (или другую) "внешнюю" обработку?

У меня есть довольно прямая вложенная структура (например, списки списков целых) и код"вращаться" через каждый из нижних уровнейКод не сложный (и не особенно длинный), но у меня есть несколько функций, которые должны «взаимодействовать» с самым низким уровнем независимо, и я просто копирую скелет цикла, чтобы сделать это.Мне кажется, что это пустая трата.

foreach (list in outerlists)
    ... a few random lines of structure traversing
    foreach (int in list)
        do something simple to int

Это явно уменьшенный пример, но мой реальный мир похож - я заканчиваю тем, что копирую внешнюю обработку многократно, чтобы изменить относительно небольшое количество внутренних линий работы.

Мое предварительное решение состоит в том, чтобы создать метод «обработки», который содержит циклы и принимает параметр перечисления (или что-то еще), чтобы сообщить ему, какую внутреннюю функцию вызывать.Затем поместите оператор switch на уровень «что-то сделать», который вызывает правильную подфункцию.

Я на правильном пути или есть более легкий путь?Я мог бы избавиться от оператора switch с помощью концепции указателей на функции (просто передать указатель на функцию в цикл обработки и вызвать его на уровне do что-то), но не знаю, возможно ли это в C #?

Ответы [ 2 ]

2 голосов
/ 14 декабря 2010

(уточняя немного об ответе Одеда)

Предполагая, что вы всегда хотите выполнять итерации одним и тем же способом, и единственное, что отличается от вставленного в копию foreach, - это самый внутренний вложенный блок, тогда вы можете инкапсулировать весь циклв метод:

public void DoStuffOnInnerElements (Action<int> theStuffToDo)
{
    foreach (var subList in outerLists)
    {
        // a few random lines here...
        foreach (int item in subList)
        {
            theStuffToDo(item);
        }
    }
}

Действие может быть любым из форматов, которые C # принимает для делегатов (делегат - это ответ C # на указатели функций C / C ++):

// Lambdas
DoStuffOnInnerElements((i) => Console.WriteLine(i));
// Methods
DoStuffOnInnerElements(My_Void_xxx_Int_Method);
DoStuffOnInnerElements(new Action<int>(Console.WriteLine));
// anonymous delegates
DoStuffOnInnerElements(delegate(int i) { Console.WriteLine(i); });
// etc.
1 голос
/ 14 декабря 2010

Вы можете передать Action делегат - это будет функция, выполняющая фактическую операцию во внешнем цикле.

...