Jader Dias
Jader Dias

Reputation: 90583

yield return works only for IEnumerable<T>?

Can I use yield return when the return type is an IGrouping<TKey, TElement> or an IDictionary<TKey, TValue>?

Upvotes: 38

Views: 21515

Answers (8)

PontiacGTX
PontiacGTX

Reputation: 365

you can always create a IAsyncEnumerable<KeyValuePair<T,V>> using a repository or list and yield return new KeyValuePair<T,V>(obj1,obj2); and a second function to call the method above that returns 'IAsyncEnumerable<KeyValuePair<T,V>>' add into a dictionary and add to the dictionary if (!dic.TryGetValue(output.Key,out object s)) assuming you want unique keys

Upvotes: 0

Daniel Earwicker
Daniel Earwicker

Reputation: 116744

Just call the iterator method and chain ToDictionary or GroupBy after it, and you have much the same thing. Put that in a one-line wrapper method if you need to call it like that from several places.

Upvotes: 2

jason
jason

Reputation: 241779

Answer: No. A yield return statement can be used only if the return type is IEnumerator, IEnumerator<T>, IEnumerable, or IEnumerable<T>.

From §8.14 of the C# 3.0 spec:

The yield statement is used in an iterator block (§8.2) to yield a value to the enumerator object (§10.14.4) or enumerable object (§10.14.5) of an iterator or to signal the end of the iteration.

From §10.14.4:

An enumerator object has the following characteristics:

  1. It implements IEnumerator and IEnumerator<T>, where T is the yield type of the iterator.

[...]

From §10.14.5:

An enumerable object has the following characteristics:

  1. It implements IEnumerable and IEnumerable<T>, where T is the yield type of the iterator.

[...]

Upvotes: 5

Marc Gravell
Marc Gravell

Reputation: 1064104

yield return works for exactly 4 cases:

  • IEnumerable
  • IEnumerable<T>
  • IEnumerator
  • IEnumerator<T>

This is because it has to build a state machine internally; a dictionary (etc) wouldn't be possible with this. You can of course just return a suitable type instead.

Upvotes: 53

Timothy Carter
Timothy Carter

Reputation: 15785

You could however return IEnumerable<KeyValuePair<K,V>> that would be similar to a dictionary. You would then yield return KeyValuePairs. You could even wrap this with another method that creates a dictionary out of the return. The only thing the first method would not guarantee is uniqueness in the keys.

Upvotes: 16

Andrew Hare
Andrew Hare

Reputation: 351698

No, because an iterator block is simply a state machine built on your behalf by the compiler. This feature allows you to "yield" and item as a portion of a sequence.

If the return type was other than IEnumerable<T> (like IDictionary for example) the compiler would have to generate methods to implement that interface and at that point it wouldn't make much sense because you would be working with a collection rather than a sequence.

Upvotes: 2

Andy
Andy

Reputation: 30418

I don't think so. While the documentation doesn't exactly spell it out, the way it is worded implies that it can only be used when the return type of the method is either IEnumerable or IEnumerable<T>. You might be able to write a class that implements IGrouping given an IEnumerable (that would be returned from your method using yield return), but that's about the only option really.

Upvotes: 1

Joel Martinez
Joel Martinez

Reputation: 47809

nope, just ienumerable :-)

Upvotes: -1

Related Questions