Разное поведение MaxItem в зависимости от типа (ref/value) T
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.04.16 17:50
Оценка: 23 (1)
Доброе время суток,

А почему у нас разное поведение MaxItem в зависимости от типа (ref/value) TValue.
В текущей реализации если source-коллекция пустая, то если TValue — value type — выкидываем исключение, а если TValue — reference type — возвращаем null.

Или я что-то упускаю?

Я бы в случае, если source пустая, выкидывал исключение, но дополнительно сделал бы метод
MaxItemOrDefault(..., Func<TSource> defaultElementIfSourceIsEmpty /* Func<> for lazy creation */)
Отредактировано 13.04.2016 18:10 MozgC . Предыдущая версия . Еще …
Отредактировано 13.04.2016 18:01 MozgC . Предыдущая версия .
Отредактировано 13.04.2016 18:01 MozgC . Предыдущая версия .
Re: Разное поведение MaxItem в зависимости от типа (ref/value) TValue
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 18:31
Оценка: 5 (1)
Здравствуйте, MozgC, Вы писали:

MC>Если source-коллекция пустая, то если TValue — value type — выкидываем исключение, а если TValue — reference type — возвращаем null.


Это соответствует поведению обычных Max/Min из фреймворка. Мотивация, видимо, в том что для реф типов есть выделенное значение null, означающее отсутствие элементов, а вот для value типов такого значения нет.
Возможно имеет смысл для value типов вертать nullable, но что важнее — консистентность между собой или консистентность с фреймворком я ответить однозначно не готов.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Разное поведение MaxItem в зависимости от типа (ref/value) TValue
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.04.16 18:51
Оценка:
Спасибо. В MoreLinq пошли по пути консистентности между собой.. Я бы тоже по этому пути пошёл.
Re[3]: Разное поведение MaxItem в зависимости от типа (ref/value) TValue
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 18:54
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Спасибо. В MoreLinq пошли по пути консистентности между собой.


В MoreLinq они вообще никуда не пошли — у них только дженерик версия.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 19:07
Оценка:
Здравствуйте, MozgC, Вы писали:

Что то я подумал, что вот так тупо переносить с типа элемента на тип контейнера логику бессмысленно. Поэтому теперь все вариации при отсутствии элементов возвращают default(TSource).
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Разное поведение MaxItem в зависимости от типа (ref/value) TValue
От: Sinix  
Дата: 13.04.16 19:07
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Возможно имеет смысл для value типов вертать nullable, но что важнее — консистентность между собой или консистентность с фреймворком я ответить однозначно не готов.


Я за фреймворк. Чтобы не переделывать код, если в FW добавят похожий вариант, а просто его использовать.
Re[3]: Разное поведение MaxItem в зависимости от типа (ref/value) TValue
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 19:13
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Я за фреймворк.


Не, логика из фреймворка нам не очень подходит, потому что тип там фигурирует другой в возвращаемом значении.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.04.16 19:26
Оценка: 46 (1) +1
Здравствуйте, AndrewVK, Вы писали:

AVK>Что то я подумал, что вот так тупо переносить с типа элемента на тип контейнера логику бессмысленно. Поэтому теперь все вариации при отсутствии элементов возвращают default(TSource).


Таким образом может быть невозможно понять, нашли ли мы элемент с максимальным значением или нет.

Представим, что у нас есть IEnumerable<Point> и надо найти точку с максимальным значением по оси Y. В коде может быть неизвестно, есть/были ли в source коллекции элементы или нет:

var maxYpoint = data.Where(d => d.SomeProperty == xxx).Select(d => d.Point).MaxItem(p => p.Y);
// maxYpoint.X & Y == 0. Значит ли это что мы нашли точку с максимальным значением Y или у нас после фильтрации вообще элементов не было?
Re[3]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 19:32
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Таким образом может быть невозможно понять, нашли ли мы элемент с максимальным значением или нет.


Можно предварительно позвать Enumerable.Empty если контейнер структура с валидным дефолтным значением и нам важно отследить отсутствие в ней элементов. В минусе только двойной запрос первого элемента.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[4]: Разное поведение MaxItem в зависимости от типа (ref/v
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.04.16 19:39
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Можно предварительно позвать Enumerable.Empty если контейнер структура с валидным дефолтным значением и нам важно отследить отсутствие в ней элементов.

Не распарсил.

AVK>В минусе только двойной запрос первого элемента.

Это может быть очень жирный минус. Первый элемент, удовлетворящий условию фильтрации, может находится ближе к концу последовательности. Или итерация может быть дорогой операцией. Вот у меня сейчас реальная задача по обработке терабайта данных. Во время этой обработки нужно тысячи раз проанализировать последовательности из миллионов элементов. Требования к производительности и памяти жёсткие.
Отредактировано 13.04.2016 19:45 MozgC . Предыдущая версия . Еще …
Отредактировано 13.04.2016 19:45 MozgC . Предыдущая версия .
Отредактировано 13.04.2016 19:44 MozgC . Предыдущая версия .
Re[4]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: Sinix  
Дата: 13.04.16 19:47
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:


AVK>Можно предварительно позвать Enumerable.Empty если контейнер структура с валидным дефолтным значением и нам важно отследить отсутствие в ней элементов. В минусе только двойной запрос первого элемента.

Я бы просто добавил MaxItemOrDefault(). Ну и переименовать в MaxBy()/MaxByOrDefault(), чтобы совпадало с Rx/Ix.
Re: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: IT Россия linq2db.com
Дата: 13.04.16 20:03
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>А почему у нас разное поведение MaxItem в зависимости от типа (ref/value) TValue.


Легко обходится преобразованием типа к nullable.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.04.16 20:08
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Я бы просто добавил MaxItemOrDefault(). Ну и переименовать в MaxBy()/MaxByOrDefault(), чтобы совпадало с Rx/Ix.


Согласен. Если коллективный разум склоняется к оставлению поведения фреймворка, то по крайней мере нужно добавить MaxByOrDefault() (я тоже за MaxBy).
Re[5]: Разное поведение MaxItem в зависимости от типа (ref/v
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 20:17
Оценка:
Здравствуйте, MozgC, Вы писали:

AVK>>Можно предварительно позвать Enumerable.Empty если контейнер структура с валидным дефолтным значением и нам важно отследить отсутствие в ней элементов.

MC>Не распарсил.
var result = sequence.Empty() ? ... : sequence.MaxItem(...);


AVK>>В минусе только двойной запрос первого элемента.

MC>Это может быть очень жирный минус.

Но точно так же этот минус будет, если нам не важно знать что в коллекции нет элеметнов, а метод выбрасывает исключение.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[6]: Разное поведение MaxItem в зависимости от типа (ref/v
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.04.16 20:48
Оценка:
Мне сейчас видится ситуация так:

Можно ничего не менять и надеяться, что люди будут знать о таком поведении (null для ref и исключение для value type) и в случае ref types будут проверять возвращаемое значение на null, а в случае структур будут использовать Cast<Point?> или DefaultIfEmpty(new Point(double.MinValue, double.MinValue)).
И такой подход конечно имеет право на жизнь.
А можно добавить методы Max/MinByOrDefault() и тогда некоторые люди, типа меня, просто сразу увидят в списке метод XxxOrDefault() и выберут его, и будут знать чего от него ожидать (т.к. имя метода сразу намекает, что в случае пустой коллекции будет возвращено дефолтное значение). И можно было бы сделать 2 перегрузки для XxxOrDefault(): одну без параметров, возвращающую default(TSource), другую — указанное пользователем значение (тут надо будет подумать в каком виде указывать это значение — Func<TSource> для ленивости, или не усложнять и просто TSource).
Re[5]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 21:08
Оценка: 18 (2)
Здравствуйте, Sinix, Вы писали:

S>Я бы просто добавил MaxItemOrDefault(). Ну и переименовать в MaxBy()/MaxByOrDefault(), чтобы совпадало с Rx/Ix.


Done
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[6]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.04.16 21:33
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Done


А можно пожалуйста сделать параметр для возможности указания дефолтного значения? Типа
MaxByOrDefault(..., TSource defaultItemIfSourceIsEmpty = default(TSource))
Re[7]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 21:36
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>А можно пожалуйста сделать параметр для возможности указания дефолтного значения?


А есть какой нибудь реальный юзкейс где это было бы полезно?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[8]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.04.16 21:45
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>А есть какой нибудь реальный юзкейс где это было бы полезно?


Последовательность структур. Возвращаемся к тому, что вернется default(Point), и я не пойму, то ли это реально точка с максимальной координатой, то ли source последовательность была пустая.
Re[9]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 22:12
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Последовательность структур. Возвращаемся к тому, что вернется default(Point), и я не пойму, то ли это реально точка с максимальной координатой, то ли source последовательность была пустая.


И что ты вернешь в случае наличия нужного параметра?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[10]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: MozgC США http://nightcoder.livejournal.com
Дата: 13.04.16 22:21
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>И что ты вернешь в случае наличия нужного параметра?


Например, new Point(double.MinValue, double.MinValue).
Re[11]: Разное поведение MaxItem в зависимости от типа (ref/value) T
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.04.16 22:30
Оценка: 16 (1)
Здравствуйте, MozgC, Вы писали:

MC>Например, new Point(double.MinValue, double.MinValue).


Поправил
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.