Pull to refresh

Comments 17

Mockk умеет мокать функции расширения. Да и многое другое котлиновское умеет
Идея в том, что разработчик пришел на проект, а вокруг код, реализованный в расширениях, и непонятно, какой метод оригинальный, а какой — метод расширения.


При одинаковых сигнатурах метода класса и функции расширения приоритет всегда будет отдаваться методу класса. Зная эту особенность понять какой именно метод будет вызываться не составит труда.
Чего только не придумают только что бы не использовать C#.
public static bool IsAdult(this User user) => user.Age >= 18;

Тут интереснее что будет если user = null? Что скажет стектрейс?
для примера fun User.isAdult() = age >= 18 user не может быть null так как не скомпиллится код, ибо Котлин это пресечет. Null в user может оказаться, если user мы будем получать скажем из джава кода, который не обеспечивает гарантию что придет не null. Если такой java метод вернет null то NPE будет. Вроде бы как — то так
В C# будет NullReferenceException в соответствующем статическом методе расширения, и это будет прекрасно видно по стектрейсу. Более того, в C#8, как и в Kotlin, можно включить null-safety, которая здорово поможет избежать ситуации с аргументами, которые нужно проверять на null.
про C# не знаю особо. круто если в C# можно null-safety включить
А почему не использовать свойства? Это ж все-таки котлин.
да можно и свойства. функции были просто для примеров
я не нашел ни одного объяснения, почему нельзя делать функции (кроме геттеров и сеттеров) в DTO

Это объяснение в расшифровке аббревиатуры DTO: data TRANSFER object. Назначение этого объекта — передача данных, а не последующее взаимодействие с этими данными. Для взаимодействия нужно делать уже свою обертку с computed свойствами (типа isAdult), методами, блэкджеком и… ну вы поняли. :)


Предназначение DTO — принести вам данные, дать вам возможность сконвертировать их в то, что вам нужно, и быстро умереть. :)

ну да. но не сказать, что прям дикоудобно. этим расширения выглядят привлекательно
ну и опять же Егор Бугаенко с вами поспорил бы. Типо объект что-то должен уметь, а не просто хранить данные. Но это уже полемика
Просто в Java нет таких языковых конструкций. Но её хотят добавить: cr.openjdk.java.net/~briangoetz/amber/datum.html
И все современные языки тем или иным способ (data-классы, структуры и тп) стараются добавить поддержку конструкций для передачи данных
Повторю то, что писал в какой-то ветке про расширения в C#: расширения позволяют придавать поведение интерфейсам, для чего (а именно для LINQ) в первую очередь и были введены в C#. Например, можно придать дефолтное поведение каким-то методам:

public interface IPagination<TItem>
{
    IEnumerable<TItem> GetPage(int offset, int size);
}

public static class PaginationExtension
{
    public static IEnumerable<TItem> GetPage(this IPagination<TItem> pagination, int offset) => pagination.GetPage(offset, 100);
}


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

Data Transfer Object подразумевает структуры, которые можно прозрачно передавать между системами. Но функции не поддаются сериализации, соот-но прозрачность нарушается.
В пользу расширений говорит тот факт, что огромная часть библиотек Kotlin написана в виде расширений. Много удобных и любимых методов для работы с коллекциями — расширения (Filter, Map и так далее). В этом можно убедиться, изучив файл _Collections.kt.

Этот пункт скорее говорит в пользу расширений на классы которые нельзя расширить, так как они поставляются сторонней библиотекой. Но никак не в пользу расширений на свои собственные.
Sign up to leave a comment.