Как интерфейс IGrouping <out TKey, out TElement> может выдавать несколько значений?

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

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

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

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

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


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

1 ответ

Решение

Если вы посмотрите на декларацию 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 framework, так это то, что он реализует существующий интерфейс и позволяет использовать его в качествеIEnumerable<TElement>напрямую, что очень мощно. Если у вашего класса есть способность, которую обещает интерфейс, реализуйте этот интерфейс. См. Также.

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

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

Другие вопросы по тегам