1

I wonder what point I overlook. IGrouping<out TKey, out TElement> is used by LINQ GroupBy. Further, the same logic is applied to ILookup, IIRC. Accordingly, they can return multiple values subject to the key specified. However, instead, I would expect the following signature to be done so.

interface IGrouping<out TKey, out IEnumerable<TElement>>
                                  ^^^^^^^^^^^^^

Originally, it implements IEnumerable<TElement> and IEnumerable for backward compatibility. Does this accomplish the same task? If yes, how? I don't understand.

public interface ILookup<TKey,TElement> : IEnumerable<IGrouping<TKey,TElement>>

Does the followed mean ILookup used by Join/GroupJoin has multiple keys with the association of multiple values? Could you exemplify? I've looked the question, but don't understand the difference, except that their lazy evaluation vs immediate evaluation semantics.


Not to do complicate matter further, but the output may help for everyone.

enter image description here

  • It is the interfaces that are implemented that satisfy the foreach/LINQ statements, the second type parameter is the type of elements that are served, the collection-behavior comes from implementing the IEnumerable interfaces. – Lasse V. Karlsen Apr 23 '20 at 17:48

1 Answers1

3

If you look at the declaration of IGrouping,

public interface IGrouping<out TKey,out TElement> : System.Collections.Generic.IEnumerable<out TElement>

You can see that it says "IGrouping<TKey, TElement> is a kind of IEnumerable<TElement>".

It's a special kind of IEnumerable<TElement>. Special in what way? It has a Key associated.


And no, this is not valid C# syntax:

interface IGrouping<out TKey, out IEnumerable<TElement>>

Remember that this is an interface declaration, and in the <>, it is declaring the type parameters, which are identifiers, for the interface. IEnumerable<TElement> is not a valid identifier. You also seem to want to refer to the existing interface System.Collections.Generic.IEnumerable<T>, but it makes no sense to put it in this place in the declaration, the same way that it wouldn't make sense to write interface Foo<List<T>> as an interface declaration in Java.

If you mean:

interface IGrouping<out TKey, out TElement> where TElement : IEnumerable

that could work, and there are many ways in which you can design this IGrouping interface. The following way probably makes sense to you the most?

interface IMyGrouping<TKey, TElement> {
    TKey Key { get; }
    IEnumerable<TElement> Elements { get; }
}

But what's really great about .NET framework's design is that it implements an existing interface, and that allows it to be used as an IEnumerable<TElement> directly, which is a very powerful thing. If your class have the ability that the interface promises, implement that interface. See also.

Does the followed mean ILookup used by GroupBy has multiple keys with the association of multiple values?

Yes. Since ILookup implements IEnumerable<IGrouping>, and IGrouping implements IEnumerable, ILookup is kind of like a IEnumerable<IEnumerable> (forgive me using the generics notation very loosely here). So an ILookup an enumerable of enumerables, i.e. like a 2D array. The difference is, that each inner "array" has a Key, since the inner "arrays" are actually IGroupings.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • I beg your pardon, my questions are generally verbose, maybe meaningless too. However, _**logically**_ is there any wrong with my syntax? And do you have any idea why the syntax is wrong? – Soner from The Ottoman Empire Apr 23 '20 at 18:02
  • _It's a special kind of IEnumerable. Special in what way? It has a Key associated._ +1, by the way. – Soner from The Ottoman Empire Apr 23 '20 at 18:08
  • @snr Not logically wrong, this is why I provided a "if you mean..." part to try to guess at what you mean by that. You are supposed to declare type parameters in those `<>`, you are not supposed to put an existing type, `IEnumerable` there. Type parameters can't be parameterised. – Sweeper Apr 23 '20 at 18:08
  • @snr See the edit. I've tried to explain/guess why .NET framework chose to design `IGrouping` this way, as opposed to some other way. – Sweeper Apr 23 '20 at 19:48
  • The difference is, that each inner "array" has a Key, since the inner "arrays" are actually IGroupings. --> is it like as exactly seen the output of the picture added? ((: – Soner from The Ottoman Empire Apr 23 '20 at 20:55
  • @snr Yes. I would think that If you have seen that picture, you should have understood what an `ILookup` is. What's your misunderstanding exactly? – Sweeper Apr 23 '20 at 20:56
  • thanks a lot sir. I'm not as much as a genius like you (: A bit hard to grasp semantics. – Soner from The Ottoman Empire Apr 23 '20 at 20:59