2010-01-23 1 views
3

Я играю с LINQ и смежными темами и задавался вопросом о следующем.Недвижимость с Перечислимым или список

У меня есть 2 метода получения последовательности Фибоначчи. Я начал с:

public static IEnumerable<int> Fibonacci 
    { 
     get 
     { 
      int i = 0; 
      int j = 1; 
      int temp = 0; 

      while (true) 
      { 
       yield return i; 

       temp = i; 
       i = j; 
       j = temp + i; 
      } 
     } 
    } 

Но это заставило меня задуматься, почему я выбираю это снова:

public static IList<int> Fibonacci(long to) 
    {    
     IList<int> fibList = new List<int>(); 
     int i = 0; 
     int j = 1; 
     int temp, index = 0; 

     while (index < to) 
     { 
      fibList.Add(i); 

      temp = i; 
      i = j; 
      j = temp + i; 

      index++; 
     } 
     return fibList; 
    } 

IList является перечислимым, а + я мог бы добавить параметризацию к нему. Я действительно не ищу оптимизацию или вещи или вещи, как использовать < long>, потому что число становится очень быстрым, его просто быстрый пример. Просто некоторые аргументы pro и con каждого метода. Почему и когда я должен использовать этот метод?

ответ

4

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

Вам также не нужно хранить весь список в памяти сразу с первой версией. Вы можете обрабатывать данные потоковым способом.

Преимущество второго заключается в том, что возврат списка позволяет вам индексировать в массив, а не обрабатывать элементы один за другим с самого начала. Вы можете использовать вторую версию, если знаете, сколько элементов вы хотите, и знаете, что список достаточно мал, чтобы вписаться в память.

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

Если у вас есть только первая версия, вы можете легко эмулировать вторую версию, используя Fibinocci().Take(20).ToList().

+1

Также: со списком вы не можете работать с результатами, пока не вычислите все числа. С помощью IEnumerable вы можете сразу начать работу с результатами и вычислить следующий номер по мере поступления. Вы сокрыли это «потоковым образом», но это было не так ясно. –

+0

Переписан первый, который будет функцией без параметров. Теперь я могу сделать: var result = Fibonacci(). TakeWhile (n => n <10000) .Skip (10); Как я хотел, спасибо :) – Oxymoron

+0

Я бы отменил это и сначала пропустил пропустить. Сохраняет необходимость выполнить проверку n <10000 на первых 10 условиях. –

0

Зачем использовать свойство (статическое или другое). Генерация числа Фибоначчи является свойством того, что ...? Кроме того, как правило, свойство никогда не должно выполнять «значительных» вычислений/обработки, поэтому вы определенно хотите использовать функцию здесь.

+0

Да, это часть служебного класса с некоторой математической функциональностью, но я как бы застрял. Он не чувствовал себя правильно, используя его как собственность. Изменено это как бесперспективная функция. – Oxymoron

0

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