2009-02-15 3 views
1

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

Этот код был поставлен Micheal Buen в потоке Writing text to the middle of a file:

 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 перед входом в тело цикла?

Благодаря

ответ

7

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

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

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

Кроме того, вы можете проверить метод 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! 
+0

Nice ASCII искусства! +1 – Kredns

+0

Да, +1 для изображения. Но список на самом деле имеет двойную связь. –

+0

Спасибо, @Henk Я нарисовал его отдельно, потому что алгоритм пересекает список только в одном направлении. – CMS

Смежные вопросы