Как можно интерфейс IGrouping дать несколько значений? - PullRequest
1 голос
/ 23 апреля 2020

Интересно, какой момент я упускаю. IGrouping<out TKey, out TElement> используется LINQ GroupBy. Кроме того, тот же лог c применяется к ILookup, IIR C. Соответственно, они могут возвращать несколько значений в зависимости от указанного ключа. Однако вместо этого я ожидал бы, что будет выполнена следующая подпись.

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

Первоначально он реализует IEnumerable<TElement> и IEnumerable для обратной совместимости. Выполняет ли это sh ту же задачу? Если да, то как? Я не понимаю.

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

Имеет ли среднее значение ILookup, используемое Join/GroupJoin, несколько ключей с ассоциацией нескольких значений? Не могли бы вы привести пример? Я посмотрел вопрос , но не понимаю разницы, за исключением того, что их ленивая оценка против семантики немедленной оценки.


Чтобы не усложнять дело дальше , но вывод может помочь всем.

enter image description here

1 Ответ

3 голосов
/ 23 апреля 2020

Если вы посмотрите на объявление IGrouping,

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

Вы можете увидеть, что оно говорит: "IGrouping<TKey, TElement> является разновидностью IEnumerable<TElement>".

Это особый вид IEnumerable<TElement>. Что особенного? С ним связан Key.


И нет, это недопустимый синтаксис C#:

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

Помните, что это интерфейс объявление и <> объявляет параметры типа, которые являются идентификаторами, для интерфейса. IEnumerable<TElement> не является допустимым идентификатором. Вы также, кажется, хотите сослаться на существующий интерфейс System.Collections.Generic.IEnumerable<T>, но нет смысла помещать его в это место в объявлении, так же, как не имеет смысла писать interface Foo<List<T>> как объявление интерфейса в Java.

Если вы имеете в виду:

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

, что может работать, и существует множество способов создания этого интерфейса IGrouping. Следующий способ, вероятно, имеет для вас наибольшее значение?

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

Но что действительно здорово в дизайне NET фреймворка заключается в том, что он реализует существующий интерфейс , и это позволяет ему использоваться как IEnumerable<TElement> напрямую, что очень мощная вещь. Если у вашего класса есть способность, которую обещает интерфейс, реализуйте этот интерфейс. См. Также .

Имеет ли среднее значение ILookup, используемое GroupBy, несколько ключей с ассоциацией нескольких значений?

Да. Так как ILookup реализует IEnumerable<IGrouping>, а IGrouping реализует IEnumerable, ILookup - это вроде как IEnumerable<IEnumerable> (простите, я здесь очень свободно использую нотацию обобщений). Таким образом, ILookup - перечислимое перечислимое число, то есть как двумерный массив. Разница в том, , что каждый внутренний "массив" имеет Key, поскольку внутренние "массивы" на самом деле IGrouping с.

...