Форум: "Основная";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];
ВнизКопирование значений свойств из одного объекта в другой Найти похожие ветки
← →
Unknown user © (2004-11-12 10:48) [0]Как скопировать значения всех public и published свойств из объекта A в объект B, не вызывая при этом методы Set..., а записывая значения непосредственно в поля. Объекты одного класса. Решения вида B.FProp1:=A.Prop1 не предлагать.
← →
Digitman © (2004-11-12 11:13) [1]общего решения не существует.
именно поэтому разработчики, отчетливо понимающее это, при копировании объектов в конечном итоге используют именно последовательность вызовов B.PropN:=A.PropN (в том или ином виде)
и только не говори что у тебя "частный" случай : был бы частный, ты бы сподобился привести конкретную декларацию и реализацию класса.
← →
PVOzerski © (2004-11-12 11:14) [2]Писать объекты так, чтобы все свойства были "завязаны" на переменные, а не на методы. И переменные эти были видимыми извне (если речь идет о разных юнитах). Ну, а то, что такое решение в большинстве случаев мало полезно - это уже вопрос другой. Объясняю: при компиляции выражения вроде B.FProp1:=A.Prop1 преобразаются в обращения к соответствующим полям или методам.
← →
Digitman © (2004-11-12 11:27) [3]
> Unknown user © (12.11.04 10:48)
> public и published
судя по присутствию этих секций в декларации класса, она будет фигурировать у тебя в интерфейсном разделе модуля.
это означает потенциальную возможность реализации наследников этого класса, что в свою очередь никак не ограничивает возможность пополнения экз-ра класса-наследника новыми свойствами, не присутствующими в предке .. и эти св-ва, возможно, реализованы не просто полями, как это выглядит в предке, а уже Get/Set-методами ..
что толку, что ты будешь иметь способ одним махом скопировать значения полей объекта класса-предка ? все равно каждый наследник отвечает за копирование своих вновь декларированных в нем св-в, а как они будут декларированы - в общем случае тебе знать не дано.
← →
Vlchel (2004-11-12 11:31) [4]Нормально в VCL это реализуется методом Assign. Он объявлен в классе TPersistent
← →
Digitman © (2004-11-12 11:42) [5]
> Vlchel (12.11.04 11:31) [4]
чего реализуется-то ?) ничего им не реализуется..
ну вызвал кто-то B.Assign(A), ну вызовет А в свою очередь в ответ на это виртуальный AssignTo(B) и за сим успокоится ..
а AssignTo()-то кто будет перекрывать (и реализовывать там все то самое, о чем здесь базар собссно и идет) ? снова бедный Пушкин ?
← →
Vlchel (2004-11-12 12:29) [6]Конечно реализовывать свой код можно только своими руками
← →
Unknown user © (2004-11-12 12:59) [7]Объясню как я до такого докатился. Возникла у меня необходимость в объектах, содержащих в себе свойства нескольких объектов такого-же класса, при этом естественно такой объект может нести в себе только совпадающие по значению свойства всех объединенных в себе объектов, а несовподающие свойства должны быть помечены как неопределенные. Пример такого объекта Selection.Font в MS Word. Создал общий для всех объектов класс
TCommonObj=class(TPersistent)
private
FChangedProps,
FUndefinedProps:TList;
FNotifyed:TCommonObj;
protected
procedure Changed(Sender:TObject); virtual;
procedure ChangedProp(AProp:string);
procedure AfterAssign(Sender:TObject); virtual;
function GetPropList(AClass:TClass; var PropCount:integer):PPropList;
procedure AddToChangedProp(PropName:string);
procedure AddToUndefinedProp(PropName:string);
procedure AddAllPropsToChanged;
procedure AddAllPropsToUndefined;
procedure ClearChangedProps;
procedure ClearUndefinedProps;
function GetCommonClass(Obj1,Obj2:TCommonObj):TClass;
procedure CopyChangedPropsTo(Dest:TCommonObj);
procedure CompareWith(AObj:TCommonObj);
public
constructor Create(ANotifyed:TCommonObj); virtual;
destructor Destroy; override;
function IsChangedProp(PropName:string):boolean;
function IsUndefinedProp(PropName:string):boolean;
end;
//******************************************************************************
function TCommonObj.GetCommonClass(Obj1,Obj2:TCommonObj):TClass;
begin
if Obj1.ClassType=Obj2.ClassType
then Result:=Obj1.ClassType
else
if Obj1.InheritsFrom(Obj2.ClassType)
then Result:=Obj2.ClassType
else
if Obj2.InheritsFrom(Obj1.ClassType)
then Result:=Obj1.ClassType
else begin
Result:=Obj2.ClassParent;
while not Obj1.InheritsFrom(Result) do
Result:=Result.ClassParent;
end;
end;
//******************************************************************************
procedure TCommonObj.CopyChangedPropsTo(Dest:TCommonObj);
var ComClass:TClass;
PropList:PPropList;
P:PPropInfo;
Vl:Variant;
Ind,PropCount:integer;
begin
if FChangedProps.Count=0 then exit;
ComClass:=GetCommonClass(Self,Dest);
PropList:=GetPropList(ComClass,PropCount);
try
for Ind:=0 to PropCount-1 do
if FChangedProps.IndexOf(PropList[Ind])>=0 then begin
P:=PPropInfo(PropList[Ind]);
Vl:=GetPropValue(Self,P.Name);
if P.PropType^^.Kind=tkSet then
if VarType(Vl)=varInteger then
SetOrdProp(Dest,P,Vl) else
if VarToStr(Vl)<>"" then
SetSetProp(Dest,P,VarToStr(Vl))
else SetOrdProp(Dest,P,0)
else SetPropValue(Dest,P.Name,Vl);
end; {if}
finally
FreeMem(PropList);
end;
end;
//******************************************************************************
procedure TCommonObj.CompareWith(AObj:TCommonObj);
var ComClass:TClass;
PropList:PPropList;
Ind,PropCount:integer;
S:string;
Vl1,Vl2:Variant;
begin
ComClass:=GetCommonClass(Self,AObj);
PropList:=GetPropList(ComClass,PropCount);
try
for Ind:=0 to PropCount-1 do
if PropList[Ind]^.PropType^.Kind<>tkMethod then begin
S:=PropList[Ind]^.Name;
Vl1:=GetPropValue(Self,S);
Vl2:=GetPropValue(AObj,S);
if (Vl1<>Null) and (Vl2<>Null) and (Vl1<>Vl2)
then AddToUndefinedProp(S);
end; {if}
finally
FreeMem(PropList);
end;
end;
//******************************************************************************
procedure TCommonObj.AddToChangedProp(PropName:string);
var P:PPropInfo;
begin
P:=GetPropInfo(PTypeInfo(Self.ClassInfo),PropName);
if (P<>nil) and (FChangedProps.IndexOf(P)<0)
then FChangedProps.Add(P);
end;
//******************************************************************************
procedure TCommonObj.AddToUndefinedProp(PropName:string);
var P:PPropInfo;
begin
P:=GetPropInfo(PTypeInfo(Self.ClassInfo),PropName);
if (P<>nil) and (FUndefinedProps.IndexOf(P)<0)
then FUndefinedProps.Add(P);
end;
//******************************************************************************
function TCommonObj.IsChangedProp(PropName:string):boolean;
var P:PPropInfo;
begin
Result:=false;
P:=GetPropInfo(Self,PropName);
if P<>nil then Result:=FChangedProps.IndexOf(P)>=0;
end;
//******************************************************************************
function TCommonObj.IsUndefinedProp(PropName:string):boolean;
var P:PPropInfo;
begin
Result:=false;
P:=GetPropInfo(Self,PropName);
if P<>nil
then Result:=FUndefinedProps.IndexOf(P)>=0;
end;
Где в списке FUndefinedProps хранятся ссылки на свойства, значения которых неопределлено.
При вызове Assign потомками TCommonObj копировать надо значения только тех свойств которые определенны, а постоянно вызывать IsUndefinedProp("PropName") не хочется. Неплохо бы использовать SePropValue, но эта процедура вызывает SetProc свойства, что в Assign недопустимо.
Подскажите еще варианты...
← →
Digitman © (2004-11-12 13:26) [8]
> Unknown user © (12.11.04 12:59) [7]
что-то какую-то жуткую кашу ты заварил, мне кажется ..
скажи, а зачем объекту знать о тек.значениях свойствах других своих "родственников" ?
ты скажи по-русски - тебе нужно "сгруппировать" по тем или иным критериям несколько "родственных" объектов и разом установить значения одноименных св-в у тех объектов, которые это св-во имеют ?
← →
Unknown user © (2004-11-12 15:02) [9]2 Digitman. Да. Но не только установить значения свойств, но и считать их. Был бы вариант попроще, я бы конечно такую кашу не заварил. Вся проблема в этих самых неопределенных значениях мульти-объекта. В MS Word для обозначения того что свойство не определенно используется константа wdUndefined. Но как там построены классы я не знаю, и как подобное реализовать в Паскале тоже не знаю. Пришлось изобретать такой вот жуткий велосипед...
← →
Digitman © (2004-11-12 15:15) [10]
> Unknown user © (12.11.04 15:02) [9]
а посмотреть, как это реализовано в коде родного дельфийского Инспектора объектов, в голову не приходило ? исходники-то имеются !
ты же не удивляешься, что Инспектор как-то умудряется показать, что общим для кучи самых разношерстных выделенных компонентов формы явл-ся одно-единственное св-вом , к примеру, Tag, и разом установить его для всех у кого оно имеется ?
все пляшет вокруг RTTI !
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.035 c