gbear wrote:
> Да блин... Вопрос, по крайней мере для меня, не в можно/не можно... А > надо/не надо. Пока всё что я видел на "голых" ссылках — это: > 1. Откровенно плохой дизайн. > 2. Решается другими способами... без делатов и ссылок на методы.
Пока всё что я видел на "голых" делегатех — это:
1. Откровенно плохой дизайн.
2. Решается другими способами... без делагатов.
Здравствуйте, Павел Кузнецов, Вы писали:
>> ISO, как я понимаю, стандарты прорабатывает и принимает. А подают их как раз разные ECMA, ANSI и т.п.
ПК>Это хорошее замечание, но применительно к C++, в составе ISO существует соответствующая рабочая группа (JTC 1/SC 22/WG 21), что и определяет требования к процессу по работе над стандартом C++.
И все же не стоит смеяться даже над С++ программистом не знающим такую мелочь.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, IT, Вы писали:
IT>Насколько мне известно, анонимные делегаты — это просто синтаксический сахарок. Никаких новых концепций в язык они не привносят.
Не совем так. Захват контекста метода в котором они объявлены (кстати, все же анонимные методы) кое что дает. По крайней мере он открывает целый мир функционального программирования с кучей своих паттернов.
Ну, и синтаксический сахар — это очень не мало. В конце концов когда-то if тоже казался синтаксическии сахаром.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
V>>В общем, Страуструп просто напросто не стал ограничивать возможности разработчика автоматически "за кулисами" генеренным классом.
E>Да-да. Поэтому разработчики, так классно неограниченные Страуструпом, должны были сначала дождаться введения шаблонов в С++, а потом сидеть и куковать до XXI века, пока компиляторы не научились делать частичную специализацию. В каком году вышел VC++ 7.0? Предыдущую версию компилятора ты небрежно оставил за бортом.
К Sinclair-у претензий нет. Он писал о компиляторах С++ и не обобщал свои выводы до C#.
VD>>Так вот я тебе скажу. Сначала это была ошибка дизайнера языка. А теперь неумение ее признать и гордыня.
E>Так вот я тебе скажу, что созданный на основе опыта Ada (где уже были generic-и), C++ (с шаблонами) и Java (с виртуальной машиной и рефлекшеном) C# даже не получил generic-ов в первой версии, этого пришлось ждать еще 3 года. Хотя их можно было бы тупо скопировать. А вот были ли в 85-ом году концепции делегатов в том виде, в котором они тебе нравятся -- это еще бООльшой вопрос.
В C# практически небыло ошибок. И те что были устраняются. Именно по этому я смотрю на него как на перспективный язык. А что до наличия концепций и умения их слизать... Вот сегодня концепции делегатов есть и очень хорошо проработаны. Но ни Ява, ни С++ даже не пытаются их слизать. А жаль.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, vdimas, Вы писали:
V>А я до сих пор не понимаю, почему они сразу не выпустили свой C# с генериками? Тем более в 2002-м?
Думаю, боялись сделать ошибок. В 2002 дженерики были только в зачатке.
V>Э нет, это не ссылка на метод. Это ссылка на объект, который хранит в себе указатель на экземпляр класса и выполняет делегирование вызова определенного метода класса.
Я не знаю кто "это". Я вижу маразм. Нужно одно, а пытаются навязать другое. Нужна ссылка на метод объекта. Точка! Именно это и пытаются сэмулировать гуру в биндах, сигналах и т.п.
V>Указатели на ф-ии в С++ есть,
Только на глобальные функции. И не в С++, а в С. С++ просто тупо содрал удачное решение.
V> и этого достаточно для произвольного оперирования ими.
Какое еще "орпределение имени"? Этого не достаточно для полноценного ООП.
V> Да и нам не всегда нужно делегирование вызова третей стороне.
Всегда, не всегда. Нужно? Так не чего выдумывать.
V>Ничто. В QT слоты и сигналы очень давно. QT, кстати, тоже графическая приблуда.
Тоже как что?
V> Вот тебе и ответ, насчет 85-х.
А сколько QT лет? И причем тут С++? Почему в язык не встраивается необходимая и такая простая фича?
VD>>Так вот я тебе скажу. Сначала это была ошибка дизайнера языка. А теперь неумение ее признать и гордыня.
V>
+1
V>Сначала это было элементарно невостребовано,
Чушь. Это было востребовано и использовалось еще в С 20 лет назад.
V> а теперь это уже есть,
"Этого" так и нет. Есть эмуляция.
V> да еще и в гораздо более мощном виде, чем в C#.
Очередное необоснованное заявление.
V> Предоставляемые возможности просто несравнимы.
Это точно. По этому видимо С++ подходит к гробовой доске.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, vdimas, Вы писали:
VD>>Ты пример приведи где я делегатами не смогу реализовать твои изыски. Пойми, это просто более универсальная и гибкая сущьность.
V>Наоборот — это ограниченная сущность. Делегат умеет лишь передавать управление тратьей стороне. Более общая сущность — это callback. В С++ у тебя есть куча производных от нее.
Пример будет? Нет? Тогда досвидания. Слушать это мне уже надоело. Хочется немного аргументов.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
V>Чтобы подменять этот объект. (Behaviour — паттерны)
Подменить? Запроста. Подменяется ссылка на делегат. Паттерн поведение и без этого правда делается на раз, но на делегатах вообще изумительно.
V>Например, этот делегат используется уже очень многими объектами, и огранизовывать подписывание-отписывание может быть делом накладным или даже невозможным, ибо экземпляр нашего делегата мог быть передан "еще неизвестно куда", в какой-нить плагин.
Пример невозможного примера в студию.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, gbear, Вы писали:
G>>К сожалению, по ссылке задачу обнаружить не удалось... Да и... ка бы это сказать-то... Ну мне, например, вот так сразу в голову и не лезет, какой-нибудь из Behaviour паттернов, для реализации которого необходимы ссылки на методы. G>>Просветите — тогда и поговорим.
V>Ты очень правильно выделил слово необходимы. Известно, что любая задача решается множеством способов, и чем этот способ проще — тем лучше.
Проще... не всегда тот критерий. В смысле, проще с какой точки зрения? Проще сейчас... Или будет проще когда-либо потом. И т.п. Или что, Вы вкладываете в это понятие?
Необходимость решения — по мне — суть, композиция критериев. Каких конкретно критериев — зависит от конкретной ситуации, в рамках которой, обсуждается необходимость использования данного решения. В общем случае понятие необходимости определить, мне, не представляется возможным. Если у Вас есть такое — готов его выслушать и обсудить.
V>А насчет просвещения — в С++ я часто видел ситуацию, когда внутри объекта есть множества методов с одинаковой сигнатурой (зачастую — приватных методов), и есть внутри этого же объекта переменная — указатель на метод (иногда статическая, иногда нет). И есть некий внешний фасадный метод, который лишь вызывает целевой метод по указателю. Этот указатель на метод меняется в зависимости от внешних условий, т.е. указывает на разные целевые ф-ии.
И что? В том, смысле, что мне непонятно что именно Вы пытаетесь до меня донести этой фразой?
V>В дотнете я тоже видел решение подобных задач, спомощью длиннююющей цепочки if. V>Теперь просветил?
Т.е. Ваша задача выглядит так:
Есть некоторое поведение, реализация которого зависит от внешних факторов.
На пальцах:
1. Есть набор методов (N) имеющих одинаковую сигнатуру.
2. В зависимости от внешних условий, в одной и той же ситуации должны вызываться различные методы из N.
Так?
И сразу вопрос... Почему у Вас почему весь набор N содержится в одном классе?
Т.е. если у нас есть некоторое поведение, реалиация которого должна зависить от внешних факторов, то не логичней ли для каждой из возможных реализаций данного поведения иметь свой класс? С точки зрения дизайна такая композиция гораздо "симпатишней" — т.к. при добавленнии новой реализации данного поведения мы не затрагиваем имеющуюся иерархию.
G>>Более общ по стравнению с "голым" указателем... В том смысле, что тип делегата не связан с типом делегируемого объекта.
V>Замечательно, а некий шаблон, требующий у типа-параметра лишь operator() — разве не более общее решение (не возможное в дотнет, кстати)? Ведь под этот параметр лезут и глобальные ф-ии, и статические и объекты-функторы и ссылки на таковые (И переходники-делегаты в т.ч. как частный случай функционального объекта)
Естественно. Только я ведь не телепат. То что, мне предоставил Евгений — то и использовал.
G>>Спасибо... читали. Просто это дисскусия слепого с глухим. Вам говорят о том, что уж если "около трех миллионов" программистов постоянно изобретают велосипед на тему, то почему бы не включить этот велосипед в язык. Миллионы мух, как известно, ошибаться не могут. А три миллиона программистов, по всему выходит, что ошибаются... Так чтоль?
V>А может составим более подробный список, чего уж там мелочиться? Да в язык можно еще столько всякой хрени воткнуть А ты там о каких-то несчастных делегатах. Ну НЕ ПРОБЛЕМА ЭТО, понимаешь. Действительно, разговор слепого с глухим.
Поскипано... Вы поймите меня... я лишь попытался объяснить Вам, то как мне представляется та ветка дискуссии на которую Вы сослались. Вот и все. Самому мне гораздо интересен совсем другой аспект. А именно — необходимость. Для того чтобы обсуждать этот аспект нужны примеры... Пока что все примеры которыя я наблюдал — суть — примеры использования.
V>А первая же кака с рефлекшеном — это наличие нескольких перегруженных методов с одним именем, тебе GetMethod() вернет первый попавшийся, так что при билиотечной реализации твоего примера это частенько не будет работать.
Да ну?! А сигнату значит в GetMethod передавать не судьба? Смахивает на "если не пользоваться хакерским приведением типов в стиле С, или приведением через void".
V>К выражению "плохой дизайн" тут немного чуствительны. Можно пару слов о сути виденных тобой ошибках дизайна?
А то я не в курсе
Для начала спрошу... Вы смотрели те примеры которые приводил Евгений? Вы считаете их образцом для подражания с точки зрения дизайна?
Здравствуйте, Cyberax, Вы писали:
C>Пока всё что я видел на "голых" делегатех — это: C>1. Откровенно плохой дизайн. C>2. Решается другими способами... без делагатов.
Что есть "голый" делегат?! Если Вы ещё не поняли — то под "голыми" ссылками на метод в этой подветке понимаются — ссылки не связанные с объектами.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, vdimas, Вы писали:
VD>>>Ты пример приведи где я делегатами не смогу реализовать твои изыски. Пойми, это просто более универсальная и гибкая сущьность.
V>>Наоборот — это ограниченная сущность. Делегат умеет лишь передавать управление тратьей стороне. Более общая сущность — это callback. В С++ у тебя есть куча производных от нее.
VD>Пример будет? Нет? Тогда досвидания. Слушать это мне уже надоело. Хочется немного аргументов.
Привет!
Да сколько угодно. Только определись поточнее, пример чего именно тебе нужен, ok? И приведу в наилучшем виде.
Попутный вопрос. В дотнет (не в C#) возможны глобальные ф-ии. Делегаты их поддерживают?
-----------
Лучше бы тебе надоело безаргументно писать в конце каждого своего поста "потому что это лучше и проще". Ибо, как только речь заходит о конкретных примерах, так обычно выходит как минимум не легче и не проще, в лучшем случае так же.
Здравствуйте, Cyberax, Вы писали:
C>Например, есть коллекция векторов (трехмерные векторы), у каждого нужно вызвать фукнцию normalize. Как вы это сделаете с делегатами?
А зачем это делать с помощью делегатов
Может мы будем исходить из реальных задач? А то ведь точно так же я могу попросить тебя сделать это на C++ через Reflection
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
V>>Чтобы подменять этот объект. (Behaviour — паттерны)
VD>Подменить? Запроста. Подменяется ссылка на делегат. Паттерн поведение и без этого правда делается на раз, но на делегатах вообще изумительно.
То, что его можно сделать на интерфейсах — это понятно, просто мне не нравится каждый раз городить новый интерфейс ради одной сигнатуры ф-ии (многим не нравится).
V>>Например, этот делегат используется уже очень многими объектами, и огранизовывать подписывание-отписывание может быть делом накладным или даже невозможным, ибо экземпляр нашего делегата мог быть передан "еще неизвестно куда", в какой-нить плагин.
VD>Пример невозможного примера в студию.
например вот:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace test {
internal class Class1 {
bool Action1(EmfPlusRecordType recordType, int flags, int dataSize, IntPtr data, PlayRecordCallback callbackData) {
// тут я хочу в зависимости от условий менять Action на другойreturn true;
}
bool Action2(EmfPlusRecordType recordType, int flags, int dataSize, IntPtr data, PlayRecordCallback callbackData) {
return false;
}
bool Action3(EmfPlusRecordType recordType, int flags, int dataSize, IntPtr data, PlayRecordCallback callbackData)
{
return false;
}
static Metafile GetMetafile()
{
return null; // заглушка
}
static void Main(string[] args) {
Class1 c1 = new Class1();
Graphics g = new Graphics();
Metafile mf = GetMetafile();
g.EnumerateMetafile(mf, new Point(0, 0), new Graphics.EnumerateMetafileProc(c1.Action1));
}
}
}
во всех подобных случаях на дотнет я должен создавать доп. уровень коссвенности в виде доп. ф-ии, в то время как на С++ я имею возможность непосредственно подставлять в свой делегат указатель на требуемую ф-ию.
1. На каждую сигнатуру ф-ии ручками написать класс-переходник у котого описать:
— событие — агрегат для других делегатов
— метод — переходник для некоего "внешнего" делегата, внутри метода надо вызвать событие (проверив его на null предварительно)
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Cyberax, Вы писали:
C>>Например, есть коллекция векторов (трехмерные векторы), у каждого нужно вызвать фукнцию normalize. Как вы это сделаете с делегатами?
IT>А зачем это делать с помощью делегатов IT>Может мы будем исходить из реальных задач? А то ведь точно так же я могу попросить тебя сделать это на C++ через Reflection
Ну да, делегаты в таких случаях на дотнет и на фиг не упали. Все эти вещи делаются на дотнет императивно, путем написания нескольких методов (а скольких нескольких?), каждый из которых содержит три вложенных foreach и просто вызывает 1 определенный метод над элементом коллекции.
Правда, возникают траблы с дистпечеризацией в run-time, когда конкретный метод задается внешними условиями... Ну тут дотнету и рефлекшен в руки
А еще интереснее, когда мы должны некую внешнюю ф-ию заставить пройтись по элементам коллекции. Например, у нас есть плагин, и нам доступны ф-ии из него (заведомо известной сигнатуры). Тут надо делать делегат на внешние методы, опять же — CreateDelegate работает через рефлекшн.
------
Тут все участники беседы сидели на плюсах в разное время, думаю понятно, как на С++ такое делается проще в декларативном стиле?
К тому же, вызов ф-ии по адресу не дороже обычного виртуального вызова.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Павел Кузнецов, Вы писали:
>>> Ну это как раз сделать совсем несложно. Как бы ты это делал на плюсах?
ПК>>Я знаю, что это сделать несложно (по крайней мере, если есть анонимные делегаты). Вопрос не в сложности, а в осмысленности. Имхо, бессмысленным такое действо называть как-то странно.
IT>Я думаю, что делегат без объекта и с объектом — это совершенно две разных вещи как с точки зрения имплементации так и концепции.
Насколько разные с т.з. вызвающей стороны? С этой т.з. делегат — суть посредник/адаптер, осуществляющий делегирование вызова целевому алгоритму. Это может быть "устойчивый" алгоритм — т.е. метод класса + экземпляр, либо "неустойчивый" аналог статической ф-ии.
С т.з. обсуждаемого примера — это не важно, и полностью определяется целями и задачами целевого алгоритма. Если мы хотим накопить некую статистику об элементах коллекции — то разумнее использовать делегат с объектом (хотя, в однопоточной программе это не обязательно ), если же нужно просто произвести некие операции над объектами — то зачастую подходят статические методы. В чем разница концепций?
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, eao197, Вы писали:
E>>И тратить время на создание каждый раз, когда требуется всего лишь делать вызов.
AVK>
Интересно. Единственное, что мне не нравится, так это то, что сессия создает у себя методы для проверки Pdu в зависимости от версии. Но это уже придирки.
А вот второе решение мне понравилось меньше, так как оно менее очевидно, вероятно дольше исполняется и, как здесь vdimas, кажется упоминал, что будет, если у Pdu будет несколько перегруженных методов CheckVer с разными сигнатурами? (последнее -- опять придирка )
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, AndrewVK, Вы писали:
V>>Слово "пользовательский" — ключевое. Аттрибуты сами по себе ничего не делают, кто должен что-то сделать для их использования. Ничем не хуже мини-велосипедов для С++.
AVK>Отличие пользовательского кода в том, что он пишется несколько раз. Но, впрочем, и код, который это все реализует тоже несложен. Вот, собственно, он весь:
Андрей, я не против этого подхода. Более того, сам по-максимуму стараюсь автоматизировать все что подается автоматизации. И "декларативность" подхода — наилучший способ использования автоматизации.
Дело в том, что если я подобную автоматизацию делаю в С++ (там свой способ декларативности подхода), и заметь, тоже весьма небольшими кусками кода — не более твоего примера, то определенные личности мнгновенно пытаются прилепить ярлыки "велосипедостроителя".
Посмотри, что именно я сказал в том посте.
И то, что ты привел кусок кода из реального проекта, необходимый для одного лишь типа аттрибута — весьма кстати, позволяет оценить относительный вес велосипеда к целевым задачам.
Ну а теперь попытаемся прикинуть относительный вес велосипеда — С++-ного делегата/сигнала/биндера/еще_пара_названий к использующему его коду?
В подобных спорах у меня возникает всегда 1 вопрос — а из-за чего собсно спор? В этой ветке пытаюсь отстоять свою позицию (бесполезность подобных споров), показывая бенефиты и недостатки обеих технологий.
Просто сам спор, с подачи аппологетов одной из т.з. перешел из плоскости обсуждения фич ЗА, в выискивание всевозможных ПРОТИВ.
Кто-то же должен аргументированно отвечать на каждый выпад ПРОТИВ, с целью элементарного баланса?
А так — ничего личного...
Здравствуйте, vdimas, Вы писали:
C>>>Например, есть коллекция векторов (трехмерные векторы), у каждого нужно вызвать фукнцию normalize. Как вы это сделаете с делегатами?
IT>>А зачем это делать с помощью делегатов IT>>Может мы будем исходить из реальных задач? А то ведь точно так же я могу попросить тебя сделать это на C++ через Reflection
V>Ну да, делегаты в таких случаях на дотнет и на фиг не упали. Все эти вещи делаются на дотнет императивно, путем написания нескольких методов (а скольких нескольких?), каждый из которых содержит три вложенных foreach и просто вызывает 1 определенный метод над элементом коллекции.
Может я конечно не правильно понял условие задачи, но из того как ты его сформулировал следует, что это делается одним циклом по коллекции "трейхмерных векторов" и вызовом у них метода normalize.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, eao197, Вы писали:
E>А вот второе решение мне понравилось меньше,
Зря. Оно намного ближе к идеологии дотнета.
E> так как оно менее очевидно,
Кому? Мне очевидно . А прикладной программист ничего этого не увидит, ему главное атрибуты развешать.
E> вероятно дольше исполняется
Нет. Скорость исполнения обоих вариантов примерно одинакова (отличается на время выборки из хештаблицы), а время инициализации при старте программы не особо критично. А вот метода Establish, если ты заметил, нет вобще.
E> и, как здесь vdimas, кажется упоминал, что будет, если у Pdu будет несколько перегруженных методов CheckVer с разными сигнатурами? (последнее -- опять придирка )
Ну наверное логику нужно будет соответственно поправить. Так тут и с плюсовыми указателями на методы тоже так просто не прокатит. И опять же зависит от того зачем эти перегрузки. Если просто для передачи неких статических данных, то намного проще и удобнее просто расширить атрибут.
Здравствуйте, vdimas, Вы писали:
V>Дело в том, что если я подобную автоматизацию делаю в С++ (там свой способ декларативности подхода), и заметь, тоже весьма небольшими кусками кода — не более твоего примера, то определенные личности мнгновенно пытаются прилепить ярлыки "велосипедостроителя".
Приведи пример. Уж с чем точно у С++ проблемы, так это с метаданными.
V>И то, что ты привел кусок кода из реального проекта, необходимый для одного лишь типа аттрибута — весьма кстати, позволяет оценить относительный вес велосипеда к целевым задачам.