Используете ли вы оператор yield return? Например следующий код:

public static IEnumerable<Item> GetGoodItems(this IEnumerable<Item> items) {  
     if (items != null)  
        foreach (var item in items) {  
          if (item.Type == ItemType.Good)  
                       yield return item;  
        }  
}  

Возвращает либо пустую коллекцию либо коллекцию IEnumerable. Причем работает очень шустро.

Тематическая статья на тему так называемых «ленивых вычислений» от пользователя Olostan.

Примеры от Дона Бокса.

Еще один интересный пример от Джастина Эзередж(Justin Etheredge) — метод, возвращающий бесконечный IEnumerable:

static void Main()  
{  
    foreach (BigInt value in NaturalNumbers())  
    {  
        Console.WriteLine(value);  
    }  
  
}  
  
public static IEnumerable<BigInt> NaturalNumbers()  
{  
    var result = new List<BigInt>();  
    BigInt value = 0;  
  
    for(;;)  
    {  
        value++;  
        result.Add(value);  
    }  
  
    return result;  
}