Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.09.16;
Скачать: [xml.tar.bz2];

Вниз

Не могу разобраться как работает метод 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.022 c
4-51012
Hogo
2002-07-22 09:25
2002.09.16
HOOK для DOS приложений


6-50900
the fate
2002-07-11 08:19
2002.09.16
Как с помощью делфи прослушать сокет?


1-50845
Vover
2002-09-04 15:02
2002.09.16
Help me


1-50678
Mazenrat
2002-09-04 18:33
2002.09.16
Переворот TrackBar.


1-50758
victor_ch
2002-09-04 10:04
2002.09.16
Проблема со вставкой даты во Freereport





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский