Форум: "Основная";
Текущий архив: 2005.10.02;
Скачать: [xml.tar.bz2];
Внизis и classname Найти похожие ветки
← →
Val © (2005-09-07 17:34) [0]есть код:
if Assigned(FMyObj) and (FMyObj is TMyClass) then
(FMyObj as TMyClass).DosomeThing;
при отладке условие (FMyObj is TMyClass) не выполняется, хотя я вижу, что FMyObj.ClassName = "TMyClass". Почему?
← →
Digitman © (2005-09-07 17:39) [1]
> при отладке ..не выполняется, хотя я вижу ..
видишь где ? в Evaluate/Modify ?
← →
Val © (2005-09-07 17:45) [2]да.
← →
Digitman © (2005-09-07 17:49) [3]ну чудес-то не бывает)
хочешь сказать, что в Evaluate/Modify ..
FMyObj.ClassName = "TMyClass"
и в то же время в том же Evaluate/Modify ..
FMyObj is TMyClass = False ?
← →
DesWind © (2005-09-07 17:53) [4]Мож тут собака порылась - Assigned(FMyObj)?
← →
Val © (2005-09-07 17:56) [5]дополню:
if Assigned(FMyObj) then
TMyClass(FMyObj).DosomeThing;
так работает но это не safe coding, насколько я понимаю и так работает:
if Assigned(FMyObj) and FMyObjClassNameIs("TMyClass") then
TMyClass(FMyObj).DosomeThing;
но что же с is и as? - вылазит invalid class typecast при таком коде:
if Assigned(FMyObj) then (FMyObj as TMyClass).DosomeThing;
нет. Assigned() = true.
чудес не бывает. но ситуация есть.
← →
Digitman © (2005-09-07 17:56) [6]
> DesWind © (07.09.05 17:53) [4]
если Assigned(FMyObj)=False, то каким, спрашивается, макаром автор получил зн-е ClassName ?)
← →
REA (2005-09-07 18:05) [7]А не в DLL ли тут дело?
← →
Digitman © (2005-09-07 18:06) [8]
> Val © (07.09.05 17:56) [5]
у тебя ссылка в FMyObj "битая" (неактуальная)
← →
Digitman © (2005-09-07 18:08) [9]
> REA (07.09.05 18:05) [7]
вполне м.б. что и в длл .. разные RTTI...
← →
Val © (2005-09-07 19:13) [10]врядли битая. другие варианты обращения ведь работают.
что накопал:
дело в том что is равен true, если сравнивать с классом-предком.
TParentMyClass = class of TParentClass;
TMyClass = class(TParentClass)
..
Сам объект создается как TParentMyClass(TMyClass).Create.
и тогда (FMyObj is TMyClass) = false, но (FMyObj is TParentClass) = true, хотя FMyObj.ClassName = TMyClass.
так что же проверяет is, объясните?
← →
Val © (2005-09-07 19:22) [11]>[3] Digitman © (07.09.05 17:49)
нет, dll нет, есть bpl.
кстати, забыл сказать из-за проблем с сервером:
и в то же время в том же Evaluate/Modify ..
FMyObj is TMyClass = False ?
этого нет, есть Expression illegal in evaluator.
← →
DiamondShark © (2005-09-07 21:01) [12]
> нет, dll нет, есть bpl.
Не прошло и трёх часов, как появился хоть какой-то намёк на то, откуда берутся объекты.
Теперь бы ещё достаточное описание происходящего -- где описаны классы, как обращаешься с пакетом -- и будет совсем замечательно.
← →
Defunct © (2005-09-08 01:28) [13]Val © (07.09.05 19:22) [11]
Либо Build with runtime packages (решит проблему сразу).
либо вместо is использовать прямую проверку:
if Obj.ClassName = TMyClass.ClassName then ...
> так работает но это не safe coding
> ...
> if Assigned(FMyObj) and FMyObjClassNameIs("TMyClass") then
Раз уж ты печешься о safe coding, почему допускаешь условие при котором возможно обращение к not Assigned объекту?
пиши уже так:
if Assigned( Obj ) then
if Obj is TMyClass then
...
или так:
if Assigned( Obj ) then
if Obj.ClassName = TMyClass.ClassName then
...
> но что же с is и as? - вылазит invalid class typecast при таком коде:
> if Assigned(FMyObj) then (FMyObj as TMyClass).DosomeThing;
используй конструкцию:
TMyClass( Obj ) вместо (Obj as TMyClass).
печатать меньше и вероятность возникновения invalid type cast гораздо меньше.
← →
ЮЮ © (2005-09-08 03:52) [14]>Сам объект создается как TParentMyClass(TMyClass).Create.
странное "приведение типов" для конструктора. Ты уж определись, какого класса нужен объект и напиши прямо, без извращений.
З.Ы. контструктор можно сделать и виртуальным, как у TComponent
← →
Defunct © (2005-09-08 03:58) [15]> З.Ы. контструктор можно сделать и виртуальным, как у TComponent
и что это даст?
← →
ЮЮ © (2005-09-08 07:34) [16]>и что это даст?
Возможность создавать экземпляр класса по заданному типу (имени).
Зачем-то же автору потребовалось "приведение типов"
← →
Val © (2005-09-08 11:27) [17]>DiamondShark © (07.09.05 21:01)
? это код из самого пакета. не стоит язвить - спросили бы я бы сказал сразу. я не знал, что это имеет принципиальное значение для данного вопроса. и сейчас так не думаю, если честно.
>[13] Defunct © (08.09.05 01:28)
Либо Build with runtime packages (решит проблему сразу)
нет, поскольку так и компилится.
Раз уж ты печешься ..
Больше никто кроме меня не печется?
По сути - это понятно. но...это отлаживаемый код, в котором я точно знаю, что ссылка существует и валидна. Кроме того у меня не выставлена "complete boolean eval", что означает, насколько я понимаю, что второе условие не будет вычисляться при первом = false для and.
используй конструкцию:...
совет не вреден в свете safe coding?
>ЮЮ © (08.09.05 03:52)
нет, не странное.
класс получается динамически, по имени из бд. метод для создания и инициализации общий для ряда классов имеющих одного предка.
определиться не могу - это корпоративный код, который я раскопал, пока ковырял ошибку.
>All
коллеги, я понимаю, что ошибку я могу обойти простым приведением, могу поставить проверку на имя класса - все будет работать.
Но я хочу понять и за этим обратился к вам - что(какое свойство?) проверяет оператор is, раз может возникать подобная ситуация?
← →
DesWind © (2005-09-08 11:50) [18]Digitman © (07.09.05 17:56) [6]
ClassName если я не ошибаюсь это - class function, можно вызывать и без создания объекта.
← →
Erik1 © (2005-09-08 12:52) [19]Тебе тут дали один намек, например в dll есть известная проблема если создаются два класса один в dll а другой в основной программе, то при сравнении у них окажутся разные типы. А bpl это расширеная dll вроде при использовании bpl эту проблему можно обойти, но тут есть нуансы.
Если хочеш решить проблему кординально, приведи как создовался объект и где! Как он передовался, сделай контроль сразу после создания объекта и получиш все ответы.
← →
Val © (2005-09-08 13:23) [20]>Erik1 © (08.09.05 12:52)
я говорил уже - не причем это. он и после создания(код в одной bpl) и в момент выполнения приведенного кода(код в другой bpl) обладает теми же, интересующими меня свойствами - дает true при проверке на родительский класс через is но classname у него TMyClass. Понятно почему true - потому что при создании объекта использовалось приведение к классу-предку, но почему тогда остался classname TMyClass?
← →
Erik1 © (2005-09-08 13:54) [21]Хозяин барин, но зачемже тогда людей спрашивать если ты и так все прекрастно знаеш без проверки?
← →
Val © (2005-09-08 14:04) [22]Без какой проверки? В посте 20 написаны слова именно на основании проведенной ранее проверки. Если бы я все прекрасно знал, я бы не спрашивал, не так ли?
← →
Бурундук © (2005-09-08 14:18) [23]Такое может быть в такой ситуации:
Есть три пакета - bpl1, bpl2, bpl3.
В bpl1 определён класс TParent, а
в bpl2 и bpl3 TDescendant = class(TParent).
Для bpl2 и bpl3 класс TParent один, а TDescendant
у каждого свой, хотя оба идентичны (если версии совпадают).
← →
Digitman © (2005-09-08 14:22) [24]
> Val © (08.09.05 14:04) [22]
не устраивай бардак.
помощь нужна ТЕБЕ ? да, тебе.
приводи сюда весь код, касаемый что, где, как и для чего ты делаешь.
с подробнейшими комментариями.
приводи ИМЕННО это, а не не тот "шматок"-подачку, что мы тут "имели счастье лицезреть"
← →
Val © (2005-09-08 14:56) [25]>[24] Digitman © (08.09.05 14:22)
Я не устраиваю бардака и не даю никому подачек.
Я просто попытался дать абстрагированные от конкретного проекта/задачи куски кода и задал вопрос - из-за чего такое может быть в принципе(потому как место имеет) и что конкретно проверяет is. Пусть первая часть вопроса является недостаточно подкрепленной с моей стороны отрывками кода и фидбеком к уважаемым участникам ветки, я ее опущу, дабы не отнимать время, разберусь(или не разберусь) сам, но что же со второй частью?
>Бурундук © (08.09.05 14:18)
есть 2 пакета:
в bpl1 определен TParent,
в bpl2 TDescedant(TParent). В bpl2 есть еще один класс TMyClass у которого есть поле FMyObj: TParent.В одном из методов TMyClass сабжевый код, дающий ошибку.
В Bpl1 есть процедура создания объекта:
procedure MkObj(AClassName: string; var AObj: TParent);
var
AClass: TPersistentClass;
begin
AClass := GetClass(AClassName);
if AClass <> nil then
aObj := TParentClass(AClass).Create(..);
end;
← →
Игорь Шевченко © (2005-09-08 17:54) [26]А если не трудно, все-таки, неработающий код в студию
← →
Val © (2005-09-08 18:08) [27]Честно говоря, я не знаю даже, что уже показывать, поскольку ошибка в приведенных в теме ветки двух строках, в которых лишь заменены на абстрактные имена класса, объекта и метода. Скажите, какой именно участок/ки кода интересует, где происходит что? Я же не могу сюда юниты постить :(
← →
Игорь Шевченко © (2005-09-08 18:11) [28]Val © (08.09.05 18:08) [27]
> В одном из методов TMyClass сабжевый код, дающий ошибку.
Вот с этого момента поподробнее.
← →
Val © (2005-09-08 18:21) [29]вот реальный работающий метод. но только уже с проверкой на имя класса.
procedure TDealHousePaymAggrView.BtnAutoFillScheduleClick(Sender: TObject);
begin
if Assigned(FDeal) and FDeal.ClassNameIs("TDealHousePaymAggr") then
TDealHousePaymAggr(FDeal).FillSchedule;
end;
← →
Игорь Шевченко © (2005-09-08 18:31) [30]Val © (08.09.05 18:21) [29]
if FDeal is TDealHousePaymAggr then
TDealHousePaymAggr(FDeal).FillSchedule;
Будет работать при условии, если класс TDealHousePaymAggr известен как создающему объект пакету, так и использующему, то есть, его VMT находит в единственном пакете. В ином случае возможны ошибки. Кстати, is позволяет убрать проверку на Assigned, так как is от nil вернет false.
← →
Val © (2005-09-08 18:37) [31]а что означает "известен" в данном контексте?
← →
Игорь Шевченко © (2005-09-08 18:44) [32]Val © (08.09.05 18:37) [31]
Известен в данном контексте означает то, что объявлен в одном пакете с точки зрения создающей объект функции и использующей его. Например, если создающая и использующая функции находятся в одном пакете, то копия VMT для данного класса одна. А если эти функции разнесены по разным пакетам, то объявление класса должно быть вынесено в отдельный пакет.
← →
Val © (2005-09-08 18:57) [33]То есть, если бы был третий пакет bpl3, в котором объявлен этот самый TDealHousePaymAggr, в bpl1 он создавался, а в bpl2 использовался, то все было бы в порядке?
p.s. если можно - где о таких вещах можно почитать?
← →
Игорь Шевченко © (2005-09-09 10:06) [34]Val © (08.09.05 18:57) [33]
> То есть, если бы был третий пакет bpl3, в котором объявлен
> этот самый TDealHousePaymAggr, в bpl1 он создавался, а в
> bpl2 использовался, то все было бы в порядке?
Да, безусловно. Этот факт легко проверить :)
> p.s. если можно - где о таких вещах можно почитать?
На Королевстве Delphi были две неплохие статьи об использовании run-time пакетов:
http://www.delphikingdom.com/asp/viewitem.asp?UrlItem=/mastering/plugins.htm
и
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=468
← →
Val © (2005-09-09 10:10) [35]Всем участникам ветки большое спасибо за дискуссию.
Отдельное спасибо Игорю Шевченко.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.10.02;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.005 c