воскресенье, 29 мая 2011 г.

To Tuple Or Not To Tuple

Tuple (кортеж) - последовательность из конечного числа элементов.

Кортежи особенно популярны в функциональных языках программирования, где поддерживается их удобное создание, декомпозиция, pattern matching и т. д. (подробнее на примере F#). В .NET 4 появился тип Tuple, тем самым сделав массовым (до этого те, кто были в теме, писали/генерировали Tuple самостоятельно) использование кортежей и в императивных языках программирования. Однако ввиду отсутствия поддержки на уровне языка Tuple в C# превращается в простое хранилище разнородных элементов.

На первый взгляд, может показаться, что использование Tuple ввиду отсутствия необходимости создания своих типов упрощает разработку и делает ее более быстрой. Однако это ложное впечатление. Не стоит забывать, что в процессе разработки большее время занимает именно поддержка кода (да еще порой и чужого), а не сам процесс его написания. С каким из следующих кусков кода вам было бы приятнее работать: с

public void Process(Tuple<int, int> tuple)
{
...
var item = Retrieve(tuple.Item1);
...
}

или с

public void Process(IdAndValue idAndValue)
{
...
var item = Retrieve(idAndValue.Id);
...
}
?
Я бы предпочел второй вариант: у свойств есть имена, несущие некоторую семантику, что снижает сложность поддержки и уменьшает вероятность допустить ошибку. Согласитесь, по ошибке вызвать tuple.Item2 вместо tuple.Item1 гораздо проще, нежели idAndValue.Value вместо idAndValue.Id. Именно такой банальной ошибкой, которая не была отловлена тестами (потому что в тестах она была с легкостью повторена) и навеян этот пост.

Использование Tuple в C# вполне себе может быть уместно, но злоупотреблять этим не стоит.

2 комментария:

Shaddix комментирует...

В продакшн-коде использование тьюплов должно быть чем-то очень существенным обоснованно, чтобы применяться.
Собственно, передача туда-сюда анонимных типов - та же история.

В тестах тьюплы - самое то.

Idsa комментирует...

>>В продакшн-коде использование тьюплов должно быть чем-то очень существенным обоснованно, чтобы применяться.

А это совсем не очевидно. В C# за последние годы появилось много функциональных плюшек, которые очень удачно прижились. И вот появилась еще одна - логично начать использовать и ее :)

>>Собственно, передача туда-сюда анонимных типов - та же история

Анонимные типы довольно сложно передавать туда-сюда...

>>В тестах тьюплы - самое то.

В тестах - да, когда использование анонимных типов затруднено ввиду необходимости использования вспомогательных методов (из которых анонимный тип вернуть нельзя, ну или почти нельзя). Но это довольно специфичный юзкейс.