powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Сеттер проперти
35 сообщений из 35, показаны все 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
Сеттер проперти
    #40011582
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
XMLDoc один раз создается(в OnCreate) и один раз разрушается (в OnClose) главной формы, хотелось бы услышать советы в контексте данного условия.
Ну тогда все просто
Код: pascal
1.
property XMLDoc: TXMLDocument read FXMLDoc write FXMLDoc;


Док
Далее по коду у меня в основном идут проверки существования XMLDoc
Зачем? Если объект всегда создается
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011588
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док

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

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


А CloneNode не подходит? Глубоко dom.pp не смотрел.
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011736
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Зачем? Если объект всегда создается

дурная привычка проверять на все возможные ошибки, даже их вероятность ничтожно мала.


x1ca4064
А CloneNode не подходит? Глубоко dom.pp не смотрел.

есть такой
https://lazarus-ccr.sourceforge.io/docs/lazutils/laz2_dom/tdomnode.clonenode.html

т.е. так будет корректно?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure TfrmMain.SetXMLDoc(AValue: TXMLDocument);
begin
  if FXMLDoc=AValue then Exit;
  if Assigned(FXMLDoc) then FreeAndNil(FXMLDoc);
  //FXMLDoc:=AValue;
  AValue.CloneNode(True,FXMLDoc);
end; 



Кстати, хотел уточнить
Код: pascal
1.
if FXMLDoc=AValue then ...


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

не-а, при попытке создать экземпляр XMLDoc получаю отлуп
Project fb_util_wrapper raised exception class 'EDOMNotSupported' with message:
EDOMNotSupported in Cloning/importing of TXMLDocument is not supported

In file 'laz2_dom.pas' at line 1345:
raise EDOMNotSupported.Create(Format('Cloning/importing of %s is not supported', [ClassName]));
...
Рейтинг: 0 / 0
Сеттер проперти
    #40011779
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
Док
т.е. так будет корректно?

не-а, при попытке создать экземпляр XMLDoc получаю отлуп
Project fb_util_wrapper raised exception class 'EDOMNotSupported' with message:
EDOMNotSupported in Cloning/importing of TXMLDocument is not supported

In file 'laz2_dom.pas' at line 1345:
raise EDOMNotSupported.Create(Format('Cloning/importing of %s is not supported', [ClassName]));

Я что-то нигде не нашёл, что CloneNode само создаёт XMLDocument. Попробуй вместо FreeAndNil вызывать Clear (или что-там у него).
...
Рейтинг: 0 / 0
Сеттер проперти
    #40012707
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
Я что-то нигде не нашёл, что CloneNode само создаёт XMLDocument. Попробуй вместо FreeAndNil вызывать Clear (или что-там у него).

У Лазарусовского XML нет ни Clear, ни Assign - только Free, только хардкор TextContent :)

Короче, отказался я пока от этого. Перед созданием дочерней формы решил сохранять настройки формы-owner'а в файл, а после уничтожения дочки (которая меняет содержимое файла настроек) - опять грузить в хозяина настйроки из измененного файла. Слишком уж стремно где-то "потерять" ссылку на свойство и получить утечку
...
Рейтинг: 0 / 0
Сеттер проперти
    #40012777
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

А почему не пользуешься XMLPropStorage?
...
Рейтинг: 0 / 0
Сеттер проперти
    #40012808
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

чет мне как-то не зашел он, функционал показался бедным, да и компонент кривой, КМК. Может я чего не понял. В любом случае, я решил использовать пакеты Laz2_DOM и иже с ним, тем более, что они понимают UTF8.

Время будет, попробую еще JSON Tools
...
Рейтинг: 0 / 0
Сеттер проперти
    #40012815
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
чет мне как-то не зашел он, функционал показался бедным

Свойства пишет/читает, и автоматически, и кастомно. Чего тебе ещё-то нужно?
...
Рейтинг: 0 / 0
Сеттер проперти
    #40012913
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Свойства пишет/читает, и автоматически, и кастомно. Чего тебе ещё-то нужно?

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


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