Объяснение того, как работает этот код - PullRequest
1 голос
/ 16 февраля 2009

Я делаю отдельную ветку здесь, потому что я верю, что если я напишу комментарий, комментарий не продвинет эту ветку вверх и, следовательно, будет уведомление для любого, кто написал в эту ветку.

Этот код был предоставлен Micheal Buen в теме Запись текста в середину файла :

        LinkedList<string> beatles = new LinkedList<string>();

        beatles.AddFirst("John");
        LinkedListNode<string> nextBeatles = beatles.AddAfter(beatles.First, "Paul");
        nextBeatles = beatles.AddAfter(nextBeatles, "George");
        nextBeatles = beatles.AddAfter(nextBeatles, "Ringo");
        nextBeatles = beatles.AddAfter(nextBeatles, "George");
        nextBeatles = beatles.AddAfter(nextBeatles, "Ringo");

        nextBeatles = beatles.AddAfter(nextBeatles, "George");
        nextBeatles = beatles.AddAfter(nextBeatles, "Ringo");

        nextBeatles = beatles.AddAfter(nextBeatles, "George");
        nextBeatles = beatles.AddAfter(nextBeatles, "Ringo");

        nextBeatles = beatles.AddAfter(nextBeatles, "George");
        nextBeatles = beatles.AddAfter(nextBeatles, "Ringo");


        // change the 1 to your 5th line
        LinkedListNode<string> paulsNode = beatles.NodeAt(6);
        LinkedListNode<string> recentHindrance = beatles.AddBefore(paulsNode, "Yoko");
        recentHindrance = beatles.AddBefore(recentHindrance, "Aunt Mimi");
        beatles.AddBefore(recentHindrance, "Father Jim");


        Console.WriteLine("{0}", string.Join("\n", beatles.ToArray()));

        Console.ReadLine();

public static class Helper
{
    public static LinkedListNode<T> NodeAt<T>(this LinkedList<T> l, int index)
    {
        LinkedListNode<T> x = l.First;

        while ((index--) > 0)
        {
                x = x.Next;
            Console.Write(x.Value);
            Thread.Sleep(10000);
        }



        return x;
    }
}

Что мне интересно, так это то, чего достигает метод расширения?

На первом проходе x = x.Next означает, что мы смотрим на Ринго, а не на Джорджа, и так далее. Что именно происходит под капотом и что делает код с того момента, когда я вызываю NodeAt (6) и далее? Я спрашиваю об этом, так как важно иметь возможность читать и понимать код, не используя пошаговый подход в качестве помощи (иногда на работе вы будете читать код, например, в печатном документе). Кроме того, почему мы считаем в цикле в обратном направлении и почему есть скобка для вычитания 1 перед входом в тело цикла?

Спасибо

1 Ответ

7 голосов
/ 16 февраля 2009

Метод расширения только проходит по элементам LinkedList n, он инициализирует x первым элементом списка (l.First), а затем, в то же время, уменьшает индекс до шага вперед n раз (смотрите x = x.Next;):

Index:  1           2            3            4
     _ _ _ _     _ _ _ _     _ _ _ _ _     _ _ _ _
    | John  |-> | Paul  |-> | George  |-> | Ringo |
     ‾ ‾ ‾ ‾     ‾ ‾ ‾ ‾     ‾ ‾ ‾ ‾ ‾     ‾ ‾ ‾ ‾

Так что если вы вызываете метод с индексом 4 (NodeAt(4)), он получит первый элемент (Джон), уменьшит счетчик (до 3), перейдет к следующему элементу (Пол), снова уменьшит (2 ), получите следующий элемент (Джордж), уменьшите (до 1), получите следующий элемент (Ринго), а затем уменьшите до 0, и это выйдет, пока , а вернет Элемент LinkedList, в 4 позиции (Ринго).

Кроме того, вы можете проверить метод расширения ElementAt , предоставляемый System.Linq, чтобы добиться того же:

var linkedList = new LinkedList<string>(new []{"John", "Paul", "George", "Ringo"});
linkedList.ElementAt(3); // this returns you Ringo, note that 
                         // the index is 0-based!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...