Deutsch

ИИ для программиста?

49928   26 27 28 29 30 31 32 33 34 35 36 все
AlexNek патриот05.10.24 20:54
AlexNek
NEW 05.10.24 20:54 
в ответ alex445 05.10.24 20:31
С колёсиками

Зачем мне какой-то плагин еще к доске. Фигня это все ваши доски, подожду лучше, когда на нормальной доске можно будет ездить. спок

А пока играйтесь бебе

alex445 патриот05.10.24 21:04
NEW 05.10.24 21:04 
в ответ alex445 05.10.24 20:37, Последний раз изменено 05.10.24 21:13 (alex445)

Так оно и работает https://dotnetfiddle.net/lSh3Aj


Но только при выполнении. А надо при компиляции. Придумать какие-то атрибуты чтоли для классов и их членов, чтобы при компиляции были какие-то проверки.

AlexNek патриот05.10.24 21:06
AlexNek
NEW 05.10.24 21:06 
в ответ alex445 05.10.24 20:37
Вот можно сделать проверку типа внутри одного метода примерно так

Важное слово выделено...


Ну есть у вас класс конвертера. Добавили вы новый численный тип

Просто интересно, какой именно численный тип хотите добавить? смущ

Именно поэтому он и не является расширяемым.

alex445 патриот05.10.24 21:09
NEW 05.10.24 21:09 
в ответ AlexNek 05.10.24 21:06, Последний раз изменено 05.10.24 21:11 (alex445)

Ладно, тогда возвращаемся к кастомным типам от численных - смотрим на мой пример. Чем он плох, кроме того, что нет возможности заставить писать новую реализацию до выполнения. При этом нет громоздких конструкций, как у Срыва покровов, с интерфейсом и наследованием. И я чётко определяю набор типов, которые подходят - безо всяких лишних, которые могут вдруг реализовать интерфейс.


Единственное что, если начать наследоваться от моих этих типов, то выполнение уже будет не таким однозначным. Разве что закрыть их (sealed)?

alex445 патриот05.10.24 21:19
NEW 05.10.24 21:19 
в ответ alex445 05.10.24 21:09, Последний раз изменено 05.10.24 21:19 (alex445)

Ну вот, при

public class C : B {}

и вызове

Process(new C());

выдаст

В


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

AlexNek патриот05.10.24 21:51
AlexNek
NEW 05.10.24 21:51 
в ответ alex445 05.10.24 21:09
смотрим на мой пример. Чем он плох

Просто интересно, чем он хорош - всё остальное плохо хаха

Как интересно он скажет Process(new D()) нужно реализовать?

Срыв покровов патриот05.10.24 23:05
NEW 05.10.24 23:05 
в ответ alex445 05.10.24 20:37, Последний раз изменено 05.10.24 23:08 (Срыв покровов)
Method(Type1 param) => // do something
Method(Type2 param) => // do something
Method(object param) => NotSupportedException

Дед забыл принять таблетки


Удобно, чо. Вася создаст новый тип, своей метод не напишет и в рантайме вы получите исключение.


Зато не как у всех

И без интерфейсов.

alex445 патриот06.10.24 08:36
NEW 06.10.24 08:36 
в ответ Срыв покровов 05.10.24 23:05, Последний раз изменено 06.10.24 08:37 (alex445)

Вася точно таким же образом может забыть унаследоваться от вашего интерфейса. Мы уже про ваш интерфейс перетёрли, что он также не гарантирует, что придёт левый тип, реализующий этот интерфейс. Т.е. внутри всё равно надо проверять на разрешённые типы.


Вобщем, всё сводится к тому, что что-то где-то должно Васе напоминать, иначе Вася точно когда-нибудь ошибётся. В идеале надо, чтобы в каком-то одном месте был один раз добавлен разрешённый тип, и далее все проверки проходили автоматически и желательно до выполнения программы. При этом это место должно быть максимально простым и понятным. Я вобщем-то всего, чего нужно добился просто перегрузкой методов, кроме последнего - "до выполнения программы". Ваш интерфейс решает эту проблему, но усугубляет все остальные.


При этом требование "до выполнения" может быть ослаблено или убрано, если есть тесты, которые собственно и выполняют код, но делают это не в продакшене, а когда не критично.

AlexNek патриот06.10.24 11:48
AlexNek
NEW 06.10.24 11:48 
в ответ alex445 06.10.24 08:36
что он также не гарантирует, что придёт левый тип, реализующий этот интерфейс

ни один метод не даст 100% защиту. И как это левый или объект реализует конвертацию или нет. Если сказал, что реализует, никак не может быть левым.

Всё тоже самое можно сказать и о другой части. А если я сделаю перегрузку для левого объекта тогда как?


Главное, что всё логика, связанная с объектом, должна быть в объекте, а не растёрта по всему приложению.


Т.е. внутри всё равно надо проверять на разрешённые типы.

Зачем, а если и там забудешь или не то напишешь?

alex445 патриот06.10.24 12:13
NEW 06.10.24 12:13 
в ответ AlexNek 06.10.24 11:48
что он также не гарантирует, что придёт левый тип, реализующий этот интерфейс

ни один метод не даст 100% защиту.

Даст. Если у метода параметр только такого типа, то другой тип не придёт - будет ошибка компиляции. Ну, кроме приведения типа к родительскому.


Всё тоже самое можно сказать и о другой части. А если я сделаю перегрузку для левого объекта тогда как?

Это намеренное вредительство, а мы его не рассматриваем, т.к. от него защиты в рамках языка никакой нет. Намеренно не сделать новую перегрузку при создании нового типа, хотя знаешь, что надо и где надо делать эти перегрузки - это вредительство. А вот забыть сделать такие перегрузки или не знать, что их надо делать - такое бывает.


Скорее будет вариант, когда тип устарел и его можно удалить, и теперь надо удалить также все перегрузки, работающие с этим типом. Но тут уже давно есть помощь - проект не скомпилируется при отсутствующем типе, если он где-то используется.

alex445 патриот06.10.24 12:15
NEW 06.10.24 12:15 
в ответ AlexNek 06.10.24 11:48
Главное, что всё логика, связанная с объектом, должна быть в объекте, а не растёрта по всему приложению.

Методы расширения смотрят на вас с непониманием. Как и парциальные классы.

alex445 патриот06.10.24 12:20
NEW 06.10.24 12:20 
в ответ AlexNek 06.10.24 11:48, Последний раз изменено 06.10.24 12:21 (alex445)
Т.е. внутри всё равно надо проверять на разрешённые типы.
Зачем, а если и там забудешь или не то напишешь?

Вот и вопрос - какой подход лучше, если ни один не идеальный? С интерфейсов и дженериком, или с перегрузкой? Первый вариант какой-то громоздкий, задействует две сущности.


Почему в Дотнете для числовых типов в конвертерных классах решили сделать под пару десятков перегрузок - на каждый числовой тип, вместо одного простого дженерика?

AlexNek патриот06.10.24 12:28
AlexNek
NEW 06.10.24 12:28 
в ответ alex445 06.10.24 12:13, Последний раз изменено 06.10.24 12:51 (AlexNek)
Это намеренное вредительство, а мы его не рассматриваем

А дать новый тип с неправильным интерфейсом это значит не вредителсьво?

AlexNek патриот06.10.24 12:31
AlexNek
NEW 06.10.24 12:31 
в ответ alex445 06.10.24 12:15
Методы расширения смотрят на вас с непониманием

Скорее уж я смотрю на вас с непониманием смущ

Для чего нужны "Методы расширения"? Ну и они создают всего лишь иллюзию.

А с каких пор partial разбивает одни объект на два?

alex445 патриот06.10.24 12:35
NEW 06.10.24 12:35 
в ответ AlexNek 06.10.24 12:31, Последний раз изменено 06.10.24 12:41 (alex445)

Вопрос был в размазывании логики типа по проекту. Методы расширения и парциальные классы делают это успешно.


Вообще, Сишарп называется мультипарадигмальным языком. Т.е. в нём есть место не одним сектантам всяких банд, робинзонов с островов и скачущих по сценам дедков с прошедшим ярким прошлым. ))) Где-то люди всё сваливают в одно место и не дают разбредаться логике, а где-то делают прямо наоборот, ещё и всякими микросервисами шлифуют.

alex445 патриот06.10.24 12:39
NEW 06.10.24 12:39 
в ответ AlexNek 06.10.24 12:31
Скорее уж я смотрю на вас с непониманием смущ

да я вижу )))



AlexNek патриот06.10.24 12:42
AlexNek
NEW 06.10.24 12:42 
в ответ alex445 06.10.24 12:20
Почему в Дотнете для числовых типов в конвертерных классах решили сделать под пару десятков перегрузок

Ну так уже обсуждали.. Причин достаточно много.

Ну например, мы имеем ограниченное количество типов, которое в обозримое время не будет меняться.

Ну и многие методы и классы в .NET были разработаны до появления обобщений (дженериков). Поддержка перегрузок позволяет сохранить совместимость с существующим кодом и библиотеками.


И не следует сравнивать числовые типы с классами пользователя.

alex445 патриот06.10.24 12:47
NEW 06.10.24 12:47 
в ответ AlexNek 06.10.24 12:42, Последний раз изменено 06.10.24 12:51 (alex445)
Ну например, мы имеем ограниченное количество типов, которое в обозримое время не будет меняться.

Да что вы говорите! Вот ссылка на нужные и полезные людям числовые структуры (а стандартные числовые типы тоже структуры). Щёлкайте по версиям фреймворка и обнаруживайте, что появились они лишь с третьей-четвёртой версии Дотнет фреймворка (и соответствующих версий языка) и с тех пор всё расширялись. А в первой версии .NET Standard их вообще не было.


И если вам нужно конверить в том числе и эти структуры, то дописывайте расширения в стандартные классы конвертеров или пишите свои конвертеры - т.е. размазывайте логику по работе с этими типами.


Реальный мир он такой - абстракции протекают, задник с нарисованным островом провисает. )))

AlexNek патриот06.10.24 12:50
AlexNek
NEW 06.10.24 12:50 
в ответ alex445 06.10.24 12:35
Вопрос был в размазывании логики типа по проекту.

Странное у вас понимание размазывания.

Использование методов расширения для своего проекта это уже дискуссионный вопрос.

Как и разбрасывание частей одного своего класса по разным местам.


Вообще, Сишарп называется мультипарадигмальным языком. Т.е. в нём есть место

Что об этом говорят: спок


Это означает, что он поддерживает несколько различных парадигм программирования, что делает его гибким и мощным инструментом для разработчиков. Вот основные парадигмы, которые поддерживает C#:

1. Объектно-ориентированное программирование (ООП): C# изначально был разработан как объектно-ориентированный язык, поддерживающий классы, объекты, наследование, полиморфизм и инкапсуляцию.

2. Процедурное программирование: C# позволяет писать код в процедурном стиле, используя функции и процедуры для структурирования кода.

3. Функциональное программирование: В последних версиях C# были добавлены возможности для функционального программирования, такие как лямбда-выражения, функции высшего порядка и неизменяемые типы данных

1. Обобщенное программирование: C# поддерживает обобщенные типы (дженерики), что позволяет создавать универсальные и повторно используемые компоненты.

2. Событийное программирование: C# активно используется для разработки приложений с графическим интерфейсом пользователя (GUI), где события играют ключевую роль.


alex445 патриот06.10.24 12:52
NEW 06.10.24 12:52 
в ответ AlexNek 06.10.24 12:50

Вот вы могли бы так поговорить с ИИ? Нет.