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

Вниз

Не могу разобраться как работает метод Assign   Найти похожие ветки 

 
MaximatorVeter ©   (2002-09-03 15:01) [0]

Необходимо присвоить свойства одного объекта другому.

type
TSomeClass=class(TPersistent)
public
a:byte;
b:word;
c:boolean;
end;

var
SC1,SC2:TSomeClass;
begin
SC1:=TSomeClass.Create;
SC2:=TSomeClass.Create;
SC1.a:=1;
SC1.b:=2;
SC1.c:=true;
SC2.Assign(SC1); // Здесь возникает ошибка
SC1.Free;
SC2.Free;
end;


I need help!


 
valery_f   (2002-09-03 15:09) [1]

Еще-бы! У TPersistent метод Assign считай что пуст (точнее - генерит эксепшн - см. сорцы). Так что метод Assign тебе придется написать самому. Эт те не С++ с конструктором корпирования :)


 
Alx2 ©   (2002-09-03 15:10) [2]

Надо перекрыть метод
procedure AssignTo(Dest: TPersistent); virtual;
В котором расскажешь классу что надо делать.


 
Alx2 ©   (2002-09-03 15:12) [3]

> Alx2 © (03.09.02 15:10)
Почитал help. Все-таки лучше перекрыть именно assign


 
neg2001   (2002-09-03 15:14) [4]

Ну естественно будет ошибка, ведь Delphi не знает как копировать поля. Поэтому метод Assign и есть виртуальный. Ты его должен переопределить:


type
TSomeClass=class(TPersistent)
public
a:byte;
b:word;
c:boolean;
procedure Assign(Source: TPersistent); override;
end;
......
implementation


procedure TSomeClass.Assign(Source: TPersistent);
begin
inherited Assign(Source);
a:=(Source as TSomeClass).a;
.......................
end;


 
neg2001   (2002-09-03 15:18) [5]

Прошу прощения inherited не нужен

type
TSomeClass=class(TPersistent)
public
a:byte;
b:word;
c:boolean;
procedure Assign(Source: TPersistent); override;
end;
......
implementation


procedure TSomeClass.Assign(Source: TPersistent);
begin
a:=(Source as TSomeClass).a;
.......................
end;




 
MaximatorV   (2002-09-03 16:23) [6]

А все свойства (у меня их много) в цикле перебрать нельзя?


 
valery_f   (2002-09-03 16:34) [7]

2 MaximatorV (03.09.02 16:23) - Свойства перебрать можно, только вот "a:byte" и т.п. - это не свойства а просто переменные. Попробуй объединить их в записи, тогда их можно копировать "скопом" :)


 
Alx2 ©   (2002-09-03 16:36) [8]

>MaximatorV (03.09.02 16:23)
Побьют меня ногами за такой совет, но, если очень уж лень один раз нарисовать вручную их присваивание, то можно попробовать взять кусок памяти с адреса первого поля твоего объекта по адрес последнего поля и все, что между этими адресами находится, залить в соответствующий адресный интервал другого объекта с помощью move, например.


 
Бурундук   (2002-09-03 16:38) [9]

Published свойства можно.

procedure CopyPublishedProperties(Src, Dest: TObject);
var i: Integer;
Cls: TClass;

PropCnt: Integer;
PropList: PPropList;
PropInfo: PPropInfo;

function IsField(PropProc: Pointer): Boolean;
type ba = array[0..3]of Byte;
begin
Result := ba(PropProc)[3] > $FE;
end;

begin
if not Dest.InheritsFrom(Src.ClassType) then
raise Exception.CreateFmt("Cannot copy properties from %s to %s", [Src.ClassName, Dest.ClassName]);

PropCnt := GetTypeData(Src.ClassInfo)^.PropCount;
GetMem(PropList, PropCnt*SizeOf(Pointer));

try
GetPropInfos(Src.ClassInfo, PropList);

for i := 0 to PropCnt-1 do
begin
PropInfo := PropList^[i];
if (PropInfo^.Name <> "Name") then

// Какие-то св-ва, помимо Name, возможно, тоже не
// стоит копировать

begin
if PropInfo^.PropType^^.Kind = tkMethod then
SetMethodProp(Dest, PropInfo,
GetMethodProp(Src, PropInfo))
else if PropInfo^.PropType^^.Kind = tkClass then
begin
{
Cls := GetTypeData(PropInfo^.PropType^).ClassType;
if (not Cls.InheritsFrom(TComponent)) and
(Cls.InheritsFrom(TPersistent)) and
IsField(PropInfo^.SetProc)
}
if PropInfo^.Name = "Constraints"
then
// По непонятной причине свойство
// property Constraints: TSizeConstraints read FConstraints write FConstraints;
// производит запись прямо в поле, а не через Set-метод + Assign
// Поэтому приходится делать обходной маневр.
//
// Не исключено, что имеются подобные глюки и с другими (более редкими) св-вами.

TPersistent(GetObjectProp(Dest, PropInfo)).Assign
(TPersistent(GetObjectProp(Src, PropInfo)))
else
begin
SetObjectProp(Dest, PropInfo,
GetObjectProp(Src, PropInfo));
end;
end
else
SetPropValue(Dest, PropInfo^.Name, GetPropValue(Src, PropInfo^.Name));
end;
end;
finally
FreeMem(PropList, PropCnt*SizeOf(Pointer));
end;

// if (Src is TControl) then
// TControl(Dest).Parent := TControl(Src).Parent;
end;


 
MaximatorV   (2002-09-03 16:42) [10]

2 valery_f (03.09.02 16:34)

А свойства можно перебрать в цикле, основываясь на RTTI, как я догадываюсь?



Страницы: 1 вся ветка

Текущий архив: 2002.09.16;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.013 c
4-51023
SPeller
2002-07-24 19:08
2002.09.16
CreateToolbarEx


14-50945
James007
2002-08-21 14:26
2002.09.16
Вопрос о Windows....................


3-50624
Serg123
2002-08-21 13:17
2002.09.16
взаимодействие с Oracle


7-50995
wistler
2002-07-04 22:56
2002.09.16
Программирование модема.


14-50960
paul_shmakov
2002-08-21 16:21
2002.09.16
Предложение к Merlin по работе с архивами форумов