robel
robel

Reputation: 51

How to return IEnumerable<T> collection if there is one yield

What is the smartest way to use return statement in iterator block instead of foreach if I want to return input collection?

public IEnumerable<T> Filter(IEnumerable<T> collection)
{
   if (someCondition)
   {
       // return collection; - cannot be used because of "yield" bellow
       foreach (T obj in collection)
       {
          yield return obj;
       } 
       yield break;
   }
   yield return new T();
}

Upvotes: 3

Views: 550

Answers (2)

Stefan Steinegger
Stefan Steinegger

Reputation: 64648

In this case, I would probably do:

public IEnumerable<T> Filter(IEnumerable<T> collection)
{
   if (someCondition)
   {
       return collection
   }
   return new [] {new T()};
}

In more complex cases, where some collections are optionally included in the return value, I use Union.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1503469

I'm afraid that's all you can do within an iterator block. There's no equivalent of yield! in F#, or the idea of a yield foreach. It's unfortunate, but that's the way it is :(

Of course, you could avoid using an iterator block in the first place:

public IEnumerable<Class> Filter(IEnumerable<Class> collection)
{
   return someCondition ? collection : Enumerable.Repeat(new Class(2), 1);
}

Or if you have more complex logic:

public IEnumerable<Class> Filter(IEnumerable<Class> collection)
{
   return someCondition ? collection : FilterImpl(collection);
}

private IEnumerable<Class> FilterImpl(IEnumerable<Class> collection)
{
    yield return new Class(2);
    yield return new Class(1);
    // etc
}

Upvotes: 3

Related Questions