Здравствуйте, Serginio1, Вы писали:
S> Да разговор вобщето не о Delphi. Там как раз нельзя хранить данные класса в метаклассе.
Нда.
S>Тоесть есть иерархия классов у которых структура данных одинакова но по содержимому разная. Причем доступ к этим данным должен быть быстрым.
Ты вообще о чем? В общем, опять абстрактные разговоры о ложке которой на самом деле нет.
S> Виртуальные метаклассы вполне способны решить эту проблему причем ссылка на него должна быть в VMT.
Зачем? Есть обычные классы. Чем они не подходят? Нужен один экземпляр — сделай синглтон.
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Igor Trofimov, Вы писали:
iT>Извини, но я хочу вместо iT>
iT>TableCountAttribute tca = (TableCountAttribute)AttributeHelper.GetSingleAttribute(dataSetType, typeof(TableCountAttribute));
iT>if (tca == null)
iT> throw new MetadataException("Attribute TableCountAttribute not found");
iT>return tca.TableCount;
iT>
iT>писать просто iT>
iT>return dataSetType.TableCount;
iT>
iT>и не хотеть этого меня врядли кто-то заставит.
iT>Увы, но заявления о том, что настоящие кул-программеры предпочтут первый вариант я тоже за серьезные принять не могу
Т.е. у тебя не удается создать метод или класс ктотый обеспечит тебе достойную инкапсуляцию?
А причем тут язык?
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Igor Trofimov, Вы писали:
iT>Это наглядно показывает, как опыт тесного общения с языком, в котором отсутствуют какие-то возможности, корректирует наше мышление таким образом, что мы эти возможности перестаем воспринимать, мы их не замечаем, обходимся без них и потом кричим "нафиг надо?".
Все это наглядно показывает, что никакие супер-пупер современные и гибкие средства не заменят умения решать проблемы имеющимися методами.
Погляди на хоум. Там на атрибутах сделано очень много. Причем обычно вообще не нужно писать лишнего кода. Пометил что-нить атрибутом и все само работает.
Для решения твоей проблемы вообще атрибуты не нужны. Нуж всего лишь создать один класс-обертку которая считает нужные данные, закэшурует их и предоставит удобный интерфейс.
Что же касается магического "AnyDataSetType.TableCount" то на дельфи ты его тоже не плучишь.
Сгерерируй датасет, подцепи его на Дельфи 8 и попробуй.
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Lloyd, Вы писали:
VD>>Митона не знаю. Знаю только что это махровый интерпретатор с никакой производительностью по сарвению с компилируемыми средами.
L>Пастернака не читал, но осуждаю. Клоун.
Я всегда это за тобой замечал.
Что же касается интерпретаторов, то можешь попробовать доказать обратное. Люблы посмеяться знаете ли.
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Igor Trofimov, Вы писали:
iT>Оттуда же, откуда ты написал бы атрибут DataTableCountAttribute со значением 10. Конкретный тип знает это про себя.
А какой смысл вручную такие вещи вписывать?
Тогда уж нет особых проблем создать базовый тип атрибута разместить все что нужно в нем. А потом создать мелкий хэлпер который вынет тебе нужную информацию.
AVK>>Пока что твой код абсолютно бессмысленен с практической точки зрения.
iT>) Ну это же пример. Ты всегда критикуешь за практическую неприменимость примеры подходов?
Я вижу надуманность этого пимера.
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Igor Trofimov, Вы писали:
iT>Да откуда угодно. Например, при перечислении всех типов — потомков DataSet. Или из настройки/из БД. iT>Если ты хочешь мне сказать, что раз там уже знают конкретный тип, то значит, там точно знают число таблиц, то будешь неправ. Я тогда по аналогии могу сказать про виртуальные методы экземпляра — изначально объект где-то создается, там точно знают конкретный тип, вот путь и вызывают SaveCustomer() вместо virtual Save().
Блин, да на то он и экземпляр! Ты же хочешь не метаданные, а параллельной релизации ОО-фич для статической части класса. Одним словаом переворачивашь все концепции ООП. И все это вместо того чтобы просто создать синглтон.
Когда ты приводишь конкретные задачи, то тебе дают конкретные решения. Недавно ты мне тут говорил, что я не смогу вынуть число таблиц из типизированного датасета. Я тебе его вынул (бросил все и занялся поной фигней). Теперь ты утверждаешь что мол некрасиво это, кода много. Ну, напишу я тебе инкапсуляцию этого даела до одной функции, и что? Да ты скажешь, что это все фигня хочу быть царицою морскою.
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, s.ts, Вы писали:
ST>но его можно перегрузить для класса
Именно что перегрузить. Он все равно будет статическим и оператором.
ST>что это такое (не виртуальность виртуального деструктора) ?
Ну, я же говорю не нахлебался ты С++ по самые уши.
ST>это ты про то, как виртуальные методы из деструктора вызываются ?
И про наличие ключевого слова virtual у деструктора. Приходит очередной мэн в С++ пишет:
struct A
{
virtual void Clinup()
{
printf("A::Clinup()\n");
}
virtual ~A()
{
Clinup();
}
};
struct B : public A
{
virtual void Clinup()
{
/* опа... айда на форум RSDN C++ :) */
printf("B::Clinup()\n");
}
};
ST>а как реализуются виртуальные конструкторы в шарпе ? ST>это уже интересно ST>(имхо оттуда пол-шага до сабжа)
Так же как и любой другой виртуальный метод. В нем уже сформирована VMT и можно производить виртуальные вызовы.
Грабли могут быть в том, что нужно четко понимать, что этот вызов будет сделан до вызова конструкторов сабклассов.
Но так как в отличии от плюсов Шарп гарантирует инициализацию нулями, то и проблем не происходит.
ST>ну, это уже перебор ST>вызов inherited из нужного места проще воспринимается
Это тоже обсуждали. Это перенос отвественности на человека. А это самый безотвественный и ненадежный компнент в системе.
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
AVK>>А что мне твои варианты? Это варианты внутри тобой разработанного дизайна. Если такое вылазит и нормально решить проблему никак значит надо искать проблемы в дизайне. Если дизайн нормален то там не должно быть обращения к одним и тем же данным много миллионов раз, особенно если это метаданные. Явный оверхед. S> S> Ну ты глупостей то не говори. Весь нет на боксинге и унбоксинге построен,
При чем тут боксинг? Да и утверждать что весь дотнет построен на боксинге мягко говоря не стоит.
S>>>>> Обычно все данные связанные с классом тянут на объект увеличивая его размер, но увиличивая скорость доступа.
AVK>>>>Не знаю, я таких решений что то не встречал. Обычно это в твоем коде?
S>>> А ну да
AVK>>Ну тогда это не обычно, а у тебя S> Не уменя а у M$. Ты помоему что то опустил????
Здравствуйте, Igor Trofimov, Вы писали:
iT>Ты знаешь — я бы не ввязался в спор, если бы перед этим не накушался атрибутами по самое нехочу. То есть я "принял" технологию и старался ее использовать там, где она нужна — для расширения метаданных. И понял, что это далеко не так вкусно, как вы тут описываете. Один атрибут — да. Два — пожалуй. Десять, которые нужны в нескольких местах — и начинается убогое копирование кода.
iT>Не согласен с тем, что "сказал а — говори б". Все-таки источников данных все-таки есть три: iT>* явная сслка на конкретный тип iT>* вытаскивание типа из экземпляра iT>* все остальное, пожалуй можно отнести к рефлекшену.
Вот о том и речь. В первом варианте полиморфизм ничего не дает, мы и так конкретный тип знаем, во втором и в шарпе все виртуально, в третьем ни о какой типобезопасности речь не идет.
iT>И другому посоветую, потому что 90% кода будет лучше. Это тоже плюс. Производительность — это же не беременность
По поводу производительности я уже говорил. Работа с метаданными это не то место где производительность главный лимитирующий фактор. Построение в памяти структур на основе метаданных занимает небольшое время даже для приличных сборок. Все действия сверх того являются следствием ошибочного дизайна.
iT>Я не очень понял насчет "механики для любых датасетов".
А что тут непонятного? Сами по себе метаданные не представляют никакой ценности (ну разве что для каких то девелоперских тулзов). Ценность представляют экземпляры и прикладной код работает прежде всего с экземплярами. А при наличии экземпляра вполне полиморфно можно получить его тип.
iT> Но пример с датасетами я привел не совсем от балды — я недавно использовал большое кол-во строго типизированных потомков DataTable с общим корнем. Была нужна как раз общая статическая информация — маппинг на базу, ассоциации с другими классами, информация о колонках.
Ну тогда тебе стоит поглядеть на Rsdn.Framework.Data.
iT>Делал атрибутами. И хорошо представляю, что это такое.
Ты считаешь что я не представляю? Опять приведу тебе пример PG. Мне так кажется что объем кастомной информации, которую он может потреблять, особенно совместно с хостом, заметно побольше твоей задачки. Тем не менее никакого жуткого копирования кода не наблюдается. Почему так?
iT>С PG пример тебе на руку, потому что он работает с принципиально разнотипными объектами
Что значит принципиально разнотипными? Он работает прежде всего с потомками object. А многие фичи дизайнера начинают работать только если ты реализуешь IComponent. Разнотипность объектов это следствие иного подхода, а не его причина. Разнотипность только все усложняет. Если даже в сложных условиях подход дотнета ведет себя неплохо, то почему ты ожидаешь что при упрощении условий он станет работать хуже?
iT>По-моему это уже неплохо! Хотя и требует static IEnumerable. На досуге еще поищу — как чего можно было бы переписать — просто для иллюстрации.
А при чем тут виртуальные статические методы?
iT>Ну, естественно, до абсурда доводить не стоит.
А почему ты считаешь что именно в Дельфи самая неабсурдная модель? Да, у нее есть определенные преимущества, но есть и определенные недостатки. Попытки же реализовать сразу несколько подходов, как показывает практика, приводят к печальным результатам.
iT> Просто, ИМХО, существующая модель — это не два, а полтора измерения Одно — экземпляры, а половинка — типы
Существующая модель это честные два измерения, а вот модель Дельфи это не два измерения, а полтора, т.к. векторы ООП и метаданных не перпендикулярны, а коррелируют между собой. Как следствие — уменьшение пространства возможных решений, т.е. снижение гибкости
iT>Я не уверен на 100%, что понимаю все последствия
Зато я уверен что и ты и я не понимаем все последствия . Кардинальные модификации языка это очень большое исследование.
iT> (вот, страуструп тоже не понимал, к чему приведут шаблоны ) но мне кажется, что изменения были бы не так уж и серьезны.
Тут я с тобой не согласен. Тут вот недавно человек тоже считал что добавление кода в интерфейсы серьезных последствий не вызовет. Здесь та же история. Необходимость статической виртуальности тут же вызовет необходимость статической VMT. А это уже усложнение JIT. Причем это то что лежит на поверхности. А если копнуть глубже то все становится еще печальнее. Каким образом например на СВ должен вести себя ремоутинг при передаче по ссылке и по значению?
AVK>>Нет, мне нужно обоснование почему она при этом должна являться частью той же самой ООП модели что и собственно классы.
iT>Да просто потому что это вытекает из того, что уже есть. ИМХО. конечно, но все-таки она вытекает!
Вот тут то я с тобой и не согласен. Если говорить об идеологической чистоте, то попытка совместить модель данных и метаданных приводит к той самой рекурсии. Понятно что нужно где то эту рекурсию чисто исскуственно обрубить, но при этом ни о какой логичности уже речи не идет.
AVK>>Можно, но при этом компилятору пришлось бы создавать экземпляры атрибутов в процессе компиляции. iT>Ммм.. а AttributeUsage он анализирует на более низком уровне compiler magic, да?
Ага. В этом правиле есть одно исключение правда, какое не скажу , но оно своими глюками только подтверждает правило.
Здравствуйте, Serginio1, Вы писали:
AVK>>Ничего шоколадног не получится. Ты как этот Type получать собираешься? typeof? Смысла никакого нет. object.GetType()? Но он же нетипизированный, а значит результат ничем не лучше атрибутов. Assembly.GetTypes — та же фигня? Type.GetType() — и тут тоже самое. Метаклассы не избавляют от приведения, они их выносят в другое место.
S> Если объект наследник от базового типа, то приводится он к базовому типу метакласса.
Ну пойми ты одну простую вещь. Это в случае экземпляров пространство их полностью неопределено. С типами все понятно уже при компиляции, пространство их известно. Конечно остается ситуация неизвестных при компиляции сборок и тут определенный бенефит от того что вы хотите имеется, но малочисленность самих сущностей позволяет нам производить практически любую надстройку. Т.е. к примеру сравнительно небольшими усилиями можно написать библиотечку, строящую эти самые метаклассы при загрузке сборки на основании рефлекшена и атрибутов.
Здравствуйте, VladD2, Вы писали:
VD>Я всегда это за тобой замечал.
VD>Что же касается интерпретаторов, то можешь попробовать доказать обратное. Люблы посмеяться знаете ли.
Тебе чего-то доказывать? Низачто. Ты же фанатик, тебя аргументы не пронимают.
Здравствуйте, VladD2, Вы писали:
ST>>что это такое (не виртуальность виртуального деструктора) ?
VD>Ну, я же говорю не нахлебался ты С++ по самые уши.
не любитель я, знаешь ли, хлебать всякое ...
просто берешь книжку и читаешь, читаешь, читаешь...
идешь на форум и срашиваешь чего не понял...
это все до того, как всякие умные свои идеи реализовывать
очередной раз предлагаю обойтись без взаимных оценок
я когда своего страуструпа читал, он был в тонкой обложке из 200 страниц (1 или 2-е издание уж не помню)
ST>>это ты про то, как виртуальные методы из деструктора вызываются ?
VD>И про наличие ключевого слова virtual у деструктора. Приходит очередной мэн в С++ пишет: VD>
VD>struct A
VD>{
VD> virtual void Clinup()
VD> {
VD> printf("A::Clinup()\n");
VD> }
VD> virtual ~A()
VD> {
VD> Clinup();
VD> }
VD>};
VD>struct B : public A
VD>{
VD> virtual void Clinup()
VD> {
VD> /* опа... айда на форум RSDN C++ :) */
VD> printf("B::Clinup()\n");
VD> }
VD>};
VD>
ну... собственно, это нужно знать, как и синтаксис...
сейчас почему-то считается, что не нужно знать даже синтаксис, который не используешь
на самом деле все связано: автоинициализация полей/автовызов конструктора предка/"невиртуальность виртуальных функций" это должно быть так, как в C++ или наоборот, третьего не дано
если, например, убрать "невиртуальность", то, чтобы граблей (настоящих, а не тех, что по незнанию) избежать, придется автоинициализацию вводить и т.д. — тут одно другое тянет
как раз-таки я цэ нахлебался и теперь очень рад той же дельфе, хотя изначально плевался и конструкторы базового класса забывал вызывать...
ST>>а как реализуются виртуальные конструкторы в шарпе ? ST>>это уже интересно ST>>(имхо оттуда пол-шага до сабжа)
VD>Так же как и любой другой виртуальный метод. В нем уже сформирована VMT и можно производить виртуальные вызовы.
а, ты про это...
VD>Грабли могут быть в том, что нужно четко понимать, что этот вызов будет сделан до вызова конструкторов сабклассов.
VD>Но так как в отличии от плюсов Шарп гарантирует инициализацию нулями, то и проблем не происходит.
ага (выше я то же самое писал), а можно было не делать автоинициализацию, но убрать автовызов базового конструктора. и потом (как си плюсплюсники) кричать, что это дает могучую эффективность создаваемых приложений при "совсем небольшом ручном кодировании"
проблемы-то все равно будут, но они легко обходятся (в дельфе даже есть спецовый флажок в ComponentState под названием csDestroying) всякими там флажками, да декомпозицией
ST>>ну, это уже перебор ST>>вызов inherited из нужного места проще воспринимается
VD>Это тоже обсуждали. Это перенос отвественности на человека. А это самый безотвественный и ненадежный компнент в системе.
да нет, дело привычки (см. выше)
но если приходится часто переключаться между языками, где все по-разному, то да...
я вот вечно с индексацией массивов путался, а после долгописания на паскале еще и с операторами присваивания/сравнения. хорошо, что шарп это сечет четко. а вот в сях — фигня выходит ... мнда...
p.s. кстати, "самым безответственным и ненадежным компонентом" моей системы оказался борланд со своим кликсом
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Serginio1, Вы писали:
AVK>>>Ничего шоколадног не получится. Ты как этот Type получать собираешься? typeof? Смысла никакого нет. object.GetType()? Но он же нетипизированный, а значит результат ничем не лучше атрибутов. Assembly.GetTypes — та же фигня? Type.GetType() — и тут тоже самое. Метаклассы не избавляют от приведения, они их выносят в другое место.
S>> Если объект наследник от базового типа, то приводится он к базовому типу метакласса.
AVK>Ну пойми ты одну простую вещь. Это в случае экземпляров пространство их полностью неопределено. С типами все понятно уже при компиляции, пространство их известно. Конечно остается ситуация неизвестных при компиляции сборок и тут определенный бенефит от того что вы хотите имеется, но малочисленность самих сущностей позволяет нам производить практически любую надстройку. Т.е. к примеру сравнительно небольшими усилиями можно написать библиотечку, строящую эти самые метаклассы при загрузке сборки на основании рефлекшена и атрибутов.
Ну так в итоге Delphi и поступает. Разговор то о том что метаклассы это по сути тотже тип но расширенный и информация также и хранится.
Для примера
Код причем двух функций он даже преобразовывать не стал
Function GetClassStaticName(v:Tobject):String;
begin
result:= TVclass(v.ClassType).StaticVirt
end;
Function GetClassStaticName(v:TVirtClass):String;
begin
result:= v.StaticVirt
end;
Правильно преобразует в одну
public static string GetClassStaticName(object v)
{ string text1;
text1 = (TObjectHelper.ClassType(v) as @MetaTVirtClass).StaticVirt();
return text1;
}
В нативном коде просто был бы вызов по VMT статического виртуального метода, т.к. тип соотвествует декларируемому. Заметь хотя приведение и существует но приведение вынужденное. Но если бы это был не отдельный класс то приведение и не нужно так как виртуальный тип уже известен на этапе компиляции.
20.5.9 Атрибуты
Открытый тип не может использоваться внутри атрибута. Закрытый составной тип может использоваться как аргумент атрибута, но не может быть именем атрибута (attribute-name), потому что System.Attribute не может быть базовым типом для описания шаблонного класса.
class A: Attribute
{
public A(Type t) {...}
}
class B<T>: Attribute {} // Ошибка, не может использовать Attribute как базуclass List<T>
{
[A(typeof(T))] T t; // Ошибка, открытый тип в атрибуте
}
class X
{
[A(typeof(List<int>))] int x; // Ok, закрытый составной тип
[B<int>] int y; // Ошибка, неверное имя атрибута
}
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
AVK>>Т.е. к примеру сравнительно небольшими усилиями можно написать библиотечку, строящую эти самые метаклассы при загрузке сборки на основании рефлекшена и атрибутов.
S> Ну так в итоге Delphi и поступает.
И ради такой фигни корежить язык? Нафик нафик.
S>20.5.9 Атрибуты S>Открытый тип не может использоваться внутри атрибута. Закрытый составной тип может использоваться как аргумент атрибута, но не может быть именем атрибута (attribute-name), потому что System.Attribute не может быть базовым типом для описания шаблонного класса.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Serginio1, Вы писали:
AVK>>>Т.е. к примеру сравнительно небольшими усилиями можно написать библиотечку, строящую эти самые метаклассы при загрузке сборки на основании рефлекшена и атрибутов.
S>> Ну так в итоге Delphi и поступает.
AVK>И ради такой фигни корежить язык? Нафик нафик.
Да разговор то не о C# а в общем подходе и красоте решений. S>>20.5.9 Атрибуты S>>Открытый тип не может использоваться внутри атрибута. Закрытый составной тип может использоваться как аргумент атрибута, но не может быть именем атрибута (attribute-name), потому что System.Attribute не может быть базовым типом для описания шаблонного класса.
AVK>Ну блин и перевод. Нифига не понял.
Проще говоря Не может класс дженерик наследоваться от System.Attribute.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
AVK>>И ради такой фигни корежить язык? Нафик нафик. S> Да разговор то не о C# а в общем подходе и красоте решений.
Слушай, честно говоря при разговоре с тобой я последнее время уже не удивляюсь что с какого то момента ты начинаешь говорить о чем то о своем. Поэтому ты заранее предупреждай что вот тут ты начинаешь говорить о другом, иначе понимать тебя очень сложно.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Serginio1, Вы писали:
AVK>>>И ради такой фигни корежить язык? Нафик нафик. S>> Да разговор то не о C# а в общем подходе и красоте решений.
AVK>Слушай, честно говоря при разговоре с тобой я последнее время уже не удивляюсь что с какого то момента ты начинаешь говорить о чем то о своем. Поэтому ты заранее предупреждай что вот тут ты начинаешь говорить о другом, иначе понимать тебя очень сложно.
Согласен и прошу прощения. Просто форум прежде всего по Net. Считаю диалог был очень полезен (лично для меня), хотя и все остались при своем мнении.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
VD>У тебя каша в голове. Ты сам мебе постоянно противришь. То ты про метаданные. То ты про данные класса.
Прошу прощения может быть ты абсолютно прав, или я ооочень плохо объясняю.
Метаданные это суть класса такой же как и Type тот же синглтон. Со своими данными и виртуальными методами. Надеюсь ты не будешь отрицать это.
Вот данные Type
private InternalCache m_cachedData;
А данные класса могут быть как статические, но они одинаковы для всех потомков и так и виртуальные одинаковые по структуре но разные по содержимому которые могут хранится в Type (он же и метакласс).
(про атрибуты уже наслышан). И это очень полезно когда работаешь с набором классов наследуемых от единого предка и имеющих виртуальное переопределение на уровне класса за что отвечают метаклассы.
Может я плохо объясняю, но такой подход возможен и он полностью совместим с ООП.
По поводу других решений просто они менее красивы трудоемки и не типизированы.
Еще раз повторюсь если метаданные буду введены в Type или получение ссылки на них будет в VMT
То такие конструкции
Function GetClassStaticName(v:Tobject):String;
begin
result:= TVclass(v.ClassType).StaticVirt
end;
Function GetClassStaticName(v:TVirtClass):String;
begin
result:= v.StaticVirt
end;
генерят один MSIL код
public static string GetClassStaticName(TVirtClass v)
{ string text1;
text1 = (Unit.@GetMetaFromObject(v) as @MetaTVirtClass).StaticVirt();
return text1;
}
Например в Нативном Delphi был бы сразы вызван статический виртуальные метод с отрицательным смещением.
Но если бы в Net ссылка на на метакласс былабы в VMT или метакласс былбы наследником от Type то
Unit.@GetMetaFromObject(v) будет приводить не к ужасающему поиску в хэш таблице по типу, а по смещению в VMT.
А во втором случае просто не будет приведения т.к. класс известен. И за этим следит компилятор в MSIL.
Но метакласс может содержать и данные!!!!
Просто многого хочется. Чисто концептуально.
и солнце б утром не вставало, когда бы не было меня