Потомок TDataModule "создан" без.Create, но без проблем?

Я вдруг заметил TDataModuleTestExchange(nil) 'вызов конструктора' в нашей кодовой базе:

procedure TDialoogConfigExchange.ButtonTestClick(Sender: TObject);
var
   lDataModuleTestExchange: TDataModuleTestExchange;
   lResult                : Boolean;
begin
   inherited;
   [snip]
   begin
      lDataModuleTestExchange := TDataModuleTestExchange(nil);  // *** HERE ***
      try
         lResult := lDataModuleTestExchange.GetCalendarFolder(EditHost.Text,EditGebruiker.Text,EditWachtwoord.Text);
         if lResult then
            ToonMelding(sExchangeTestGelukt, mtInformation, [mbOk])
         else
            ToonMelding(Meldingen.Text, mtError, [mbOK]);
      finally
         lDataModuleTestExchange.Free;
      end;
   end;
end;

Так что вместо TDataModuleTestExchange.**Create**(nil) это работает просто отлично!

unit dmTestExchange;

interface

uses
  System.SysUtils, System.Classes,
  Xml.XMLDoc, Xml.XMLIntf, Xml.XMLDOM,
  TimeTellDM;

type
  TDataModuleTestExchange = class(TTimeTellDataModule)  // TDataModule descendant
  private
  public
    function GetCalendarFolder(const AExchangeServerURL,AExchangeLoginName,AExchangePass: String): Boolean;
  end;

Нет ошибки компилятора, нет проблем во время выполнения. Как так?

1 ответ

Решение

Прежде всего, стоит отметить, что актеры являются ложными и не служат никакой цели, кроме как сбить с толку. Код эквивалентен:

lDataModuleTestExchange := nil;

TDataModuleTestExchange.GetCalendarFolder это метод экземпляра, и вы вызываете его на nil ссылка. Это приведет к ошибке времени выполнения, если метод попытается получить доступ к любым полям в экземпляре, или вызвать виртуальные методы, или что-нибудь, что зависит от экземпляра. Таким образом, представляется вероятным, что реализация TDataModuleTestExchange.GetCalendarFolder не зависит от экземпляра. Хотя вам кажется, что здесь это сходит с рук, очевидно, что писать такой код - очень плохая форма.

Класс, вероятно, должен быть переписан для объявления метода статического класса следующим образом:

type
  TDataModuleTestExchange = class(TTimeTellDataModule)  
  public
    class function GetCalendarFolder(const AExchangeServerURL,  
      AExchangeLoginName, AExchangePass: string): Boolean; static;
  end;

А потом называется так:

lResult := TDataModuleTestExchange.GetCalendarFolder(EditHost.Text,
  EditGebruiker.Text, EditWachtwoord.Text);
if lResult then
  ToonMelding(sExchangeTestGelukt, mtInformation, [mbOk])
else
  ToonMelding(Meldingen.Text, mtError, [mbOK]);
Другие вопросы по тегам