|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
Используете ли? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 00:23 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
fkthat, норм фича ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 01:52 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
hVostt fkthat, норм фича 21962407 hVostt ЕвгенийВ, дефолтная имплементация интерфейсов настолько жуткая и сложная в использовании вещь, что если и взлетит, то очень ограниченно, в рамках каких-нибудь сложных библиотек MS за прошедшие с тех пор полтора года успел что-то сильно переделать в этой фиче? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 06:08 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
hVostt, Мне сама идея не особо как-то сначала понравилась. Но есть очень типичная ситуация, когда для удобства хочется в интерфейсе иметь больше методов, но при этом большая их часть всегда и везде будет реализовываться просто через другие методы того же интерфейса. И типовым решением для этого было использовать методы-расширения - можно посмотреть, например, как устроены интерфейсы IServiceProvider или ILogger - в них самих всего по одному методу, а все остальные "их" методы это методы-расширения. (Я сам не большой любитель расширений, но вот это, как раз случай, где расширения подходят просто идеально.) И вот, я подумал, что DIM в таких случаях могут быть удобной альтернативой: 1) Нет риска поломки из-за конфликта с "обычным" методом. 2) Нет зависимости от наличия using. 3) Можно определять свойства. Попробовал заменять расширения дефолтными методами и сразу же наткнулся на проблемы: 1) Дефолтный метод доступен только через интерфейс, но не через класс, который этот интерфейс реализует (точь в точь как explicit method implementation). Обычно это проблем вызывать не должно, т.к. DI и все используется через интерфейсы. Но, есть, все-таки, ситуации когда это может быть проблемой. Допустим, я пишу какой-то библиотечный класс и просто не хочу закладываться на то, что тот, кто его будет использовать обязательно будет использовать его через интерфейс, а не напрямую. 2) Моки. Вот это проблема уже настоящая. Castle (по крайней мере в текущей версии) не может создавать dynamic proxy для интерфейсов с дефолтными методами. Нашел в итоге обходной путь: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
Так работает, но вся конструкция в целом несколько уродливая, все это приходится делать везде где нужен мок для IFoo, и всегда надо помнить что IFoo (и другие подобные) надо мокать не напрямую, а только через вспомогательную абстрактную реализацию. В общем, покрутил я все это так и сяк, и, в том, что касается того о чем я сначала писал (заменить методы-расширения дефолтными реализациями) вернулся все-таки к старым добрым расширениям. И еще, с т.з. идеологии. Само по себе наличие у метода интерфейса реализации по-умолчанию это вполне нормально, почему бы и нет. Но синтаксически все это сделано как-то некрасиво. Интерфейс, по своей сути, это просто спецификация какого-то public API компонента. И смешивать её с кодом реализации смотрится как-то не очень. Это как если бы в файл OpenAPI сваггера можно было бы вписать какой-нибудь код на PHP с реализацией описанного там вызова :) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 11:11 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
fkthat 1) Дефолтный метод доступен только через интерфейс, но не через класс, который этот интерфейс реализует (точь в точь как explicit method implementation). Обычно это проблем вызывать не должно, т.к. DI и все используется через интерфейсы. Но, есть, все-таки, ситуации когда это может быть проблемой. Допустим, я пишу какой-то библиотечный класс и просто не хочу закладываться на то, что тот, кто его будет использовать обязательно будет использовать его через интерфейс, а не напрямую. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 11:17 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
Shocker.Pro А в чем тут проблема-то, я не понял. Если реализация есть, то она и будет использоваться, если нет, подтянется из интерфейса. Какая разница, через что это будет использоваться потребитель? Вот в чем. Возьмем интерфейс из моего примера выше и его реализацию: Код: c# 1. 2. 3. 4.
А теперь, допустим, что это часть библиотеки, которую использует кто-то другой. И такой код: Код: c# 1. 2.
у него вообще не соберется. Т.е. надо будет либо указывать в доках (которые никто не читает :), что писать можно только так: Код: c# 1. 2.
либо как-то вообще запретить использовать класс Foo напрямую (например, заставить создавать только через фабрику или фабричный метод, что отдает какими-то лишними костылями) Shocker.Pro это совсем не то же самое, что explicit method implementation Я это знаю. Я и имел в виду не "то же самое" а "ведет себя так же в плане доступа к методу". ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 11:32 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
А, дошло, да, такие кейсы я не использовал... за ненадобностью ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 11:46 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
получается, в C# подвезли множественное наследование "абстрактных классов"? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 15:48 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
Roman Mejtes получается, в C# подвезли множественное наследование "абстрактных классов"? Нет. Но это близко к "traits". ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 16:18 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
fkthat, Еще так работает. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 17:37 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
Ну очевидно удобная штука, в каком контексте ( если судить по джаве) вы пишете что то большое и монструозное, промышленный интерфейс с кучей методов, ну типа орм. Проходит время нужно добавить ряд методов, вы добавляете в интерфейс и бац. компиляция не проходит, просит их реализовать в наследниках. рутина (((( ты начинаешь рвать волосы еююй интерфейс обыкновенный класс с виртуалами ума хватило у разрабов. а тут бац default по месту обявления и в шеколаде. ( я думаю они так и сперли) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 19:06 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
Где-то в степи ( я думаю они так и сперли) это жаба обычно спирает, посмотрите на атрибуты или LINQ тут задел на будущее, в ближайших версиях .NET станет возможна прямая с жабой, последняя будет подключаться как либа с возможностью использовать все как есть, можно например отнаследоваться от жаба класса будет ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 20:33 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
ЕвгенийВ, скрестить ежа с жабой, скрепьненько )) тырят труг у друга помаленьку, а вот деревья выражений слабовато, а была бы революция в языке. скучноватый язык ( хоть и пишу на нем последние 5 лет - не мало) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 21:17 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
Roman Mejtes получается, в C# подвезли множественное наследование "абстрактных классов"? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 21:55 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
Где-то в степи вы пишете что то большое и монструозное, промышленный интерфейс с кучей методов, ну типа орм. Проходит время нужно добавить ряд методов, вы добавляете в интерфейс и бац. компиляция не проходит, просит их реализовать в наследниках. Если все это свой собственный проект, то: 1) Это врят ли особая проблема, т.к. сомнительно, что в пределах одного проекта будет хотя бы полдюжины разных реализаций одного интерфейса. 2) Если же мы решаем проблему из п.1 через DIM, то мы сразу же переносим её на юнит-тесты, в которых интерфейс мокается (как я писал выше). Все юнит-тесты которые мокают этот интерфейс сразу же поломаются. Проблемы могут быть, если этот интерфейс публикуется в составе библиотеки в качестве точки расширения (т.е. чтобы пользователь либы мог её расширить своей реализацией этого интерфейса). Сценарий, например, такой: 1) Вася создал мегафреймворк "Foo" в котором есть интерфейс IFoo для его расширения и публикует его как NuGet пакет Foo с версией 1.0.0. 2) Петя цепляет версию Foo.1.0.0 в свою либу Bar, реализует в ней свой компонент-расширение с интерфейсом IFoo, и публикует свое творение как Bar.1.0.0. 3) Васин фреймворк очень успешен, у него куча идей по его развитию, и он добавляет к своему интерфейсу IFoo еще один метод. Вася успешный инвестор опытный разработчик соблюдающий заветы SemVer, поэтому, зная, что изменение интерфейса может поломать совместимость, увеличивает мажорную версию, и свое новое произведение публикует уже как Foo.2.0.0. У Пети с этим проблем нет, потому что его пакет зависит от версии Foo.1.0.0 где интерфейс еще прежний. 4) А вот теперь мы в своем проекте цепляем одновременно либу Пети Bar.1.0.0 и фреймворк Васи Foo.2.0.0 (мы же хотим быть на острие прогресса и берем все самое последнее). И вот как раз тогда у нас все действительно падает. Но такой сценарий, все-таки, не отнесешь к тому, с чем каждый день сталкиваешься. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 22:28 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
Shocker.Pro Нет, потому что у интерфейса нет состояния fkthat Нет. Но это близко к "traits". ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 22:29 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
Сон Веры Павловны hVostt fkthat, норм фича 21962407 hVostt ЕвгенийВ, дефолтная имплементация интерфейсов настолько жуткая и сложная в использовании вещь, что если и взлетит, то очень ограниченно, в рамках каких-нибудь сложных библиотек MS за прошедшие с тех пор полтора года успел что-то сильно переделать в этой фиче? Неожиданно нашли ей применение при рефакторинге и особенно в библиотечных компонентах. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 22:56 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
fkthat 1) Дефолтный метод доступен только через интерфейс, но не через класс, который этот интерфейс реализует (точь в точь как explicit method implementation). Обычно это проблем вызывать не должно, т.к. DI и все используется через интерфейсы. Но, есть, все-таки, ситуации когда это может быть проблемой. Допустим, я пишу какой-то библиотечный класс и просто не хочу закладываться на то, что тот, кто его будет использовать обязательно будет использовать его через интерфейс, а не напрямую. Полезным дефолтные методы выглядят, например, для перегрузок. А также для базовых интерфейсов, где твоя задача — максимально уменьшить количество методов, которые нужно имплементировать. Чем это лучше расширений? Тем, что дефолтные методы интерфейса можно имплементировать, а расширения -- нет. fkthat 2) Моки. Вот это проблема уже настоящая. Castle (по крайней мере в текущей версии) не может создавать dynamic proxy для интерфейсов с дефолтными методами. Нашел в итоге обходной путь: Дефолтные методы как раз мокаются на ура. Насчёт динамик прокси, если тебе это нужно, то скорее всего ты используешь их неправильно. Это как методы расширения, только в ряде случаев лучше. Сложной логики там быть не должно. Обычно рутинное приведение, или вариации для удобного использования. Никакой логики. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 23:01 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
fkthat, судя по изложенному, этот проблема называется diamond, не проверял, но имхо компилятор пошлет вас нах, и будет требовать явный вызов, и вообще это сразу оговривалось при презентации этих фитч, и статус у них - компромисный в контесте оп. тоже самое и статик.. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 23:02 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
hVostt Дефолтные методы как раз мокаются на ура. Нет. На практике проверено. И проблема упирается как раз в Кастел (который все мок-фреймворки используют). В крайней версии Moq какой-то workaround уже встроили, но, вот, в FakeItEasy (кторым я как раз и пользуюсь) этого еще нет - по обсуждению в issues их позиция - "подождем, пока это будет поддерживаться нативно в Castle". Я, в общем, подумал тут, что может быть форкну на выходных FakeItEasy и заплатку поставлю, чтобы он с DIM работал - у меня идея уже есть как это сделать. Впрочем, ты, м.б. о том, что руками они "мокаются на ура" - но ведь это же совсем колхоз-совхоз :)) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 23:35 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
hVostt Это как методы расширения, только в ряде случаев лучше. Да, я об этом и написал, но, как видишь, там свои проблемы при этом возникают. hVostt Насчёт динамик прокси, если тебе это нужно, то скорее всего ты используешь их неправильно. Я их не использую сам, но их используют мок-фреймворки. Проблема с ними. Вот такой код сразу же кидает ексепшен: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Как обойти я уже в самом начале писал, но мне такой способ не по душе - не очень как-то красиво выглядит. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 23:40 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
hVostt, Что обидно, с Moq моки работают. Вот это вот вполне ок: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
Но, я, вот, Moq уже разлюбил и полюбил вместо него FakeItEasy за намного более компактный синтаксис. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2021, 23:58 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
fkthat Впрочем, ты, м.б. о том, что руками они "мокаются на ура" - но ведь это же совсем колхоз-совхоз :)) Эм.. ну погоди. Дефолтные методы как раз мокать не обязательно, ты мокаются те методы, которые они используют. Т.е. тут трагической проблемы нет :) Давай ситуёвину представим. Ты мокаешь свой интерфейс, а компонент юзает интерфейс через экстеншен методы. Пральна? Ты ж не можешь это замокать. То на то и выходит. Но можно и руками. В любом случае возможностей больше, чем с экстеншенами :) ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2021, 22:40 |
|
Default interface methods (C# 8)
|
|||
---|---|---|---|
#18+
fkthat Я их не использую сам, но их используют мок-фреймворки. Проблема с ними. Вот такой код сразу же кидает ексепшен: аа... ну да, проблема понятна. придётся ждать, когда подтянутся. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2021, 22:41 |
|
|
start [/forum/topic.php?fid=20&msg=40066150&tid=1398307]: |
0ms |
get settings: |
12ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
38ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 158ms |
0 / 0 |