powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Сеттер проперти
25 сообщений из 35, страница 1 из 2
Сеттер проперти
    #40010978
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть поле fXMLDoc: TXMLDocument.

Нужно сделать публичную property для нее. Что в сеттере должно быть? Как правильно сеттер написать?

=================
Док.

Win7 Ultim x64/Deb 10 (MATE; gtk3) amd64:
FB 3.0.5.33220, Lazarus 2.1(r.62825); FPC 3.3.1 (r.44456)
...
Рейтинг: 0 / 0
Сеттер проперти
    #40010981
zedxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Док,

Код: pascal
1.
2.
3.
4.
5.
6.
procedure SetXmlDoc(var AValue: TXMLDocument);
begin
  fXMLDoc.Free;
  fXMLDoc := AValue;
  AValue := nil;
end;
...
Рейтинг: 0 / 0
Сеттер проперти
    #40010985
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zedxxx

Код: pascal
1.
2.
3.
4.
5.
6.
procedure SetXmlDoc(var AValue: TXMLDocument);
begin
  fXMLDoc.Free;
  fXMLDoc := AValue;
  AValue := nil;
end;



Это не похоже на сеттер :(
...
Рейтинг: 0 / 0
Сеттер проперти
    #40010988
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
Есть поле fXMLDoc: TXMLDocument.

Нужно сделать публичную property для нее. Что в сеттере должно быть? Как правильно сеттер написать?



Зависит от того, владеет ли объект этим XMLDocument.
Я бы сделал так (добавив свойство владения):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
procedure TMyObj.SetXmlDoc(const Value:TXMLDocument);
begin
  if OwnXmlDoc then fXmlDoc.Free;
  FfXmlDoc:=Value;
end;

destructor TMyObj.Destroy;
begin
  if OwnXmlDoc then FreeAndNil(FfXmlDoc);
  ......
  inherited;
end;
...
Рейтинг: 0 / 0
Сеттер проперти
    #40010993
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

Думаю будет достаточно:

Код: pascal
1.
2.
3.
if Assigned(FXMLDocument) then 
   FreeAndNil(FXMLDocument);
FXMLDocumen.Assign(Value);
...
Рейтинг: 0 / 0
Сеттер проперти
    #40010997
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
x1ca4064,

а если так
Код: pascal
1.
2.
3.
4.
5.
procedure TMyObj.SetXmlDoc(const Value:TXMLDocument);
begin
  if Assigned(fXmlDoc) then FreeAndNil(FfXmlDoc);
  FfXmlDoc:=Value;
end;


?
...
Рейтинг: 0 / 0
Сеттер проперти
    #40010999
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMaster,

почти угадал :)

Спасибо за советы. Приду домой - попробую

зы.
Код: pascal
1.
fXmlDoc.Assign(Value)


не катит, нет в Лазаревских компонентах такого метода :(
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011001
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
x1ca4064,

а если так
Код: pascal
1.
2.
3.
4.
5.
procedure TMyObj.SetXmlDoc(const Value:TXMLDocument);
begin
  if Assigned(fXmlDoc) then FreeAndNil(FfXmlDoc);
  FfXmlDoc:=Value;
end;


?


Здесь допускается, что объект всегда владеет TXMLDocument, т.е. два объекта TMyObj не могут иметь один и тот же документ,верно ли это - решать Вам.

Возможно и другое решение - если TXMLDocument является потомком TPersistent (или как-то по другому поддерживает метод Assign) в сеттере делается копирование:
Код: sql
1.
2.
3.
4.
5.
procedure TMyObj.SetXMLDocument(const Value:TXMLDocument);
begin
  if FXMLDocument=nil then FXMLDocument:=TXMLDocument.Create;
  FXMLDocument.Assign(Value);
end;


но этот способ может быть медленным
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011016
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если без ассигна, то надо делать проверку в сеттере на равенство поля и значения. Иначе возможны проблемы.
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011023
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
не катит, нет в Лазаревских компонентах такого метода :(

Код: pascal
1.
FfXmlDoc.Parse(Value.GetXML);


🤣

Название методов взял от балды.
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011038
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_nigger
надо делать проверку в сеттере на равенство поля и значения

вроде так работает
Код: pascal
1.
2.
3.
4.
5.
6.
procedure TForm1.SetXMLDoc(AValue: TXMLDocument);
begin
  if FXMLDoc = AValue then Exit;
  if Assigned(FXMLDoc) then FreeAndNil(FXMLDoc);
  FXMLDoc:= AValue;
end;
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011039
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

Прими решение, кто управляет XMLDoc твоим...
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011045
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMaster
Прими решение, кто управляет XMLDoc твоим...

с этим как раз нет проблем
в OnCreate главной формы
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
procedure TForm1.FormCreate(Sender: TObject);
var
  RootNode, aNode: TDOMNode;
begin
  if not FileExists('settings.xml')
  then
    begin
      XMLDoc:= TXMLDocument.Create;
      RootNode:= XMLDoc.CreateElement('root');
      XMLDoc.AppendChild(RootNode);

      RootNode:= XMLDoc.DocumentElement;
      aNode:= XMLDoc.CreateElement('node_1');
      TDOMElement(aNode).AttribStrings['attr_11']:= '11';
      TDOMElement(aNode).AttribStrings['attr_12']:= '12';
      RootNode.AppendChild(aNode);

      aNode:= XMLDoc.CreateElement('node_2');
      TDOMElement(aNode).AttribStrings['attr_21']:= '21';
      TDOMElement(aNode).AttribStrings['attr_22']:= '22';
      RootNode.AppendChild(aNode);
    end
  else
    ReadXMLFile(FXMLDoc,'settings.xml');
end; 



в ее OnClose
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  if Assigned(XMLDoc) then
  try
    try
      WriteXMLFile(XMLDoc,'settings.xml');
    except
      ShowMessage(SysErrorMessageUTF8(GetLastOSError));
    end;
  finally
    XMLDoc.Free;
  end;
end;



Попробовал на тестовом проекте в другой форме поработать со свойством главной формы XMLDoc

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
procedure TForm2.FormCreate(Sender: TObject);
var
  RootNode, aNode: TDOMNode;
begin
  with Form1 do
  begin
    if not Assigned(XMLDoc) then Exit;
    RootNode:= XMLDoc.FindNode('root');
    if Assigned(RootNode) then
    begin
      RootNode:= XMLDoc.DocumentElement;
      aNode:= XMLDoc.CreateElement('childform_node_1');
      TDOMElement(aNode).AttribStrings['attr_11']:= 'childform_11';
      TDOMElement(aNode).AttribStrings['attr_12']:= 'childform_12';
      RootNode.AppendChild(aNode);

      aNode:= XMLDoc.CreateElement('childform_node_2');
      TDOMElement(aNode).AttribStrings['attr_21']:= 'childform_21';
      TDOMElement(aNode).AttribStrings['attr_22']:= 'childform_22';
      RootNode.AppendChild(aNode);
    end;
  end;
end;


- все пучком. xml-файл содержит все данные, добавляемые обеими формами

Код: xml
1.
2.
3.
4.
5.
6.
7.
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <node_1 attr_11="11" attr_12="12"/>
  <node_2 attr_21="21" attr_22="22"/>
  <childform_node_1 attr_11="childform_11" attr_12="childform_12"/>
  <childform_node_2 attr_21="childform_21" attr_22="childform_22"/>
</root>



Спасибо за советы
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011053
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

Я бы сделал через интерфейс
Не понятно, документ используется ещё где-то или нет
А ты его дестроишь )
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011079
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOU
Я бы сделал через интерфейс

я их практически не знаю, только знаком с концепцией :)
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011084
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
SOFT FOR YOU
Я бы сделал через интерфейс

я их практически не знаю, только знаком с концепцией :)

Меняешь определение XMLDoc на
Код: pascal
1.
XMLDoc: IXMLDocument 

везде, где оно используется и заменяешь везде XMLDoc.Free на
Код: pascal
1.
XMLDoc := nil; 

Главное чтобы библиотека это поддерживала.
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011117
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

Ну ты даёшь )
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011197
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOU,

Это мое хобби, а нужды не было
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011214
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

странно, что вопрос возник, а чем классика VCL не устраивает?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TForm1.SetXMLDoc(AValue: TXMLDocument);
begin
  if FXMLDoc <> AValue then 
  begin
    FreeAndNil(FXMLDoc);
    FXMLDoc:= AValue;
  end;
end;
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011217
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

В OnClose, либо поменяй местами except и finally, либо совсем убери finally.
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011248
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zelius
Док,

странно, что вопрос возник, а чем классика VCL не устраивает?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TForm1.SetXMLDoc(AValue: TXMLDocument);
begin
  if FXMLDoc <> AValue then 
  begin
    FreeAndNil(FXMLDoc);
    FXMLDoc:= AValue;
  end;
end;



Да все так. Весь вопрос собственно сводится к использованию.

Вариант 1й:

MyObject.XMLDocument.DoSome();

в этом случае XMLDocument принадлежит обьекту/классу, который и должен его создавать/разрушать. И собственно сеттера в этом случае не нужно - можно обойтись конструктором/деструктором

Вариант 2й:

MyObject.XMLDocument := NewXMLDocument;
MyObject.XMLDocument.DoSome();

Во втором варианте сеттер уже нужен (в общем случае), но вот FreeAndNil() уже становится проблематичным, т.к. только автор знает, нужно ли обнуливать документ, который уже был до этого - класс об этом не знает ни разу и вполне можно занулить используемый где-то (потом) компонент - по факту в класс попадает ссылка на что-то извне и отследить ее использование - уже на совести автора.
Поэтому наверное наиболее правильным решением будет делать копию того, что пришло извне через Assign(), если возможно или использовать интерфейсы, как уже советовали.
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011360
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
вроде так работает
Код: pascal
1.
2.
3.
4.
5.
6.
procedure TForm1.SetXMLDoc(AValue: TXMLDocument);
begin
  if FXMLDoc = AValue then Exit;
  if Assigned(FXMLDoc) then FreeAndNil(FXMLDoc);
  FXMLDoc:= AValue;
end;

Вот так работать не будет
Код: pascal
1.
2.
3.
Form2.XMLDoc := XMLDoc;
Form2.XMLDoc := nil;
Form2.XMLDoc := XMLDoc;

А дальше смотри сам.

При соблюдении принципа Тараса БульбыЗа уничтожение объекта отвечает его создательжить сильно легче
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011373
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zelius
Док,

странно, что вопрос возник, а чем классика VCL не устраивает?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TForm1.SetXMLDoc(AValue: TXMLDocument);
begin
  if FXMLDoc <> AValue then 
  begin
    FreeAndNil(FXMLDoc);
    FXMLDoc:= AValue;
  end;
end;


А если этот Value ещё где-нибудь используется? А ты потом ещё другой этому свойству назначишь?..
И да, классика - это через .Assign().
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011380
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

22219174
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011448
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
И да, классика - это через .Assign().

"Ну нету у меня, мужик, холодильника!" (с)

Нет такого метода у этого класса.


Zelius
Док,

странно, что вопрос возник, а чем классика VCL не устраивает?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TForm1.SetXMLDoc(AValue: TXMLDocument);
begin
  if FXMLDoc <> AValue then 
  begin
    FreeAndNil(FXMLDoc);
    FXMLDoc:= AValue;
  end;
end;


я про него просто не знал. Попробую и так.

Kazantsev Alexey,
ага, вижу.

To @All ,
если учесть, что я пока не стремлюсь к универсально правильному коду, то в ситуации, когда XMLDoc один раз создается(в OnCreate) и один раз разрушается (в OnClose) главной формы, хотелось бы услышать советы в контексте данного условия. Далее по коду у меня в основном идут проверки существования XMLDoc при передаче его в функции. И да, любое его безусловное уничтожение обязательно тет же сопровождается его созданием и инициализацией, типа
Код: pascal
1.
2.
3.
4.
5.
6.
7.
if Assigned(aXMLDoc) then FreeAndNil(aXMLDoc);
aXMLDoc:= TXMLDocument.Create;

//инициализируем xml-документ
RootNode:=aXMLDoc.CreateElement('config');
aXMLDoc.AppendChild(RootNode);
RootNode:= aXMLDoc.DocumentElement;



Единственное неудобство проперти в том, что для компилятора оно - константа, поэтому для манипуляций с ним либо приходится передавать его по ссылке в процедуру, либо городить лишнюю переменную
...
Рейтинг: 0 / 0
25 сообщений из 35, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Сеттер проперти
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]