Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.10.02;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.051 c
10-1105327327
Shadowy
2005-01-10 06:22
2005.10.02
Парсинг .doc в Delphi


14-1126250989
pavel_guzhanov
2005-09-09 11:29
2005.10.02
Предложение или просьба к модераторам


1-1126159000
ArtemB
2005-09-08 09:56
2005.10.02
Chart


2-1124703827
CrowD
2005-08-22 13:43
2005.10.02
Ссылки


6-1118038275
ZubrZubr
2005-06-06 10:11
2005.10.02
Просмотр Защищенного хранилища