views:

58

answers:

3

I'm playing around with LINQ and related subjects and was wondering about the following.

I've 2 methods of getting a Fibonacci sequence. I started with:

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;
            }
        }
    }  

But it got me thinking, why would I choose this over:

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 is an Enumerable as well + I might want to add some parametrization to it. I'm not really looking for optimisations or stuff or thing like use < long > because the number gets big fast, its merely a quick example. Just some arguments pro and con each method. Why and when should I use which method?

A: 

Why would you use a property (static or otherwise). A Fibonacci number generate is a property of what...? Also, as a rule of thumb, a property should never perform any "significant" calculation/processing, thus you definitely want to be using a function here.

Noldorin
Yeah, it is part of a utility class with some math functionality, but I kind of got stuck. It didnt feel right using it as a property. Changed it to be a paramterless function.
Oxymoron
A: 

If you put the first version in a foreach then it will never terminate unless you specifically break out. Potential source for a bug when using it. Maybe that's what you want, but it's something to be wary of.

Michael Bray
+4  A: 

An important difference between the two is that with your second version you have to know in advance when you want to stop, but in the first version you can start iterating and later decide when to stop. You don't have to know in advance.

You also don't have to store the entire list in memory at once with the first version. You can handle the data in a streaming manner.

An advantage of the second is that returning a list allows you to index into the array rather than handling elements one by one from the beginning. You could use the second version if you do know how many elements you want, and you know that the list is small enough to fit in memory.

Note that these differences have nothing to do with whether you use a property or a function call. You could rewrite the first to be a function call that takes no parameters.

If you have only the first version available, you could easily emulate the second version by using Fibinocci().Take(20).ToList().

Mark Byers
Also: with the List, you can't do any work with the results until you've computed all of the numbers. With an IEnumerable, you can start working with results right away and compute the next number as you go. You kinda covered that with "in a streaming manner", but it wasn't as clear.
Joel Coehoorn
Rewrote the first one to be a function without parameters.Now I can do: var result = Fibonacci().TakeWhile(n => n < 10000).Skip(10);Like I wanted, thanks :)
Oxymoron
I'd reverse that and put the skip first. Saves you having to make the the n < 10000 check on the first 10 terms.
Joel Coehoorn