Форум: "Основная";
Текущий архив: 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