2

I have a code which is similar to the following, but more complex:

IEnumerable<SomeObject> GetObjects()
{
   if (m_SomeObjectCollection == null)
   {
      yield break;
   }

   foreach(SomeObject object in m_SomeObjectCollection)
   {
      yield return object;
   }

   GetOtherObjects();
}

IEnumerable<SomeObject> GetOtherObjects()
{
...
}

I have just realized, that GetOtherObjects() method cannot be called from OtherObjects() method. There are no errors, but the iteration stops. Is there any way to solve it?

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
THE_GREAT_MARKER
  • 476
  • 4
  • 13
  • 3
    Do a `foreach` over `GetOtherObjects()` just like you did with `m_SomeObjectCollection`. – mjwills Sep 17 '19 at 13:57
  • As written, your method wouldn't need an iterator in the first place: `return m_SomeObjectCollection ?? GetOtherObjects() ?? Enumerable.Empty()` or some variation thereof should do. (Although, if you can, try to get rid of having `null` in the first place -- having collections always be instantiated, even if empty, is useful to have as an invariant.) – Jeroen Mostert Sep 17 '19 at 13:58
  • Possible duplicate of [Nested yield return with IEnumerable](https://stackoverflow.com/questions/1270024/nested-yield-return-with-ienumerable) – wimh Sep 17 '19 at 13:59

1 Answers1

6

Add foreach and yield return:

IEnumerable<SomeObject> GetObjects()
{
   if (m_SomeObjectCollection == null)
   {
      yield break;
   }

   foreach(SomeObject item in m_SomeObjectCollection)
   {
      yield return item;
   }

   foreach (var item in GetOtherObjects())
     yield return item;
}

Another possibility is Linq Concat:

Enumerable<SomeObject> GetObjects()
{
   return m_SomeObjectCollection == null
     ? new SomeObject[0] // yield break emulation: we return an empty collection
     : m_SomeObjectCollection.Concat(GetOtherObjects());  
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215