Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-1126437466
Igor_thief
2005-09-11 15:17
2005.10.02
RAVE reports


1-1126642341
The Only
2005-09-14 00:12
2005.10.02
обработка ctrl-s главной mdi формой


1-1126004967
Ш-К
2005-09-06 15:09
2005.10.02
Подгрузка DFM


1-1126701910
Jolik
2005-09-14 16:45
2005.10.02
Как узнать дополнительные сведения о файле?


1-1126087243
Michael5
2005-09-07 14:00
2005.10.02
Не получается программно растянуть форму на весь экран!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский