Is using System.Assigned () a trap? What is your opinion?

  • Автор темы emailx45
  • 250
  • Обновлено
  • 25, Jul 2019
  • #1
Initially, please, to those who are most virtuous in the knowing:
  • Do not be offended by my question! (My brain is a mess sometimes!)
  • If you are not interested, please feel free to skip this question.


It's just a question that I would like to hear from you and, if possible, an explanation of your point of view! My VCL in 32bits code test in RAD Studio 10.3.2 Arch - MSWindows 10 PRO build 1903 / 64bits

 

unit UnitMyClassX;

interface

uses

Winapi.Windows,

Winapi.Messages,

System.SysUtils,

System.Variants,

System.Classes,

Vcl.Graphics,

Vcl.Controls,

Vcl.Forms,

Vcl.Dialogs,

Vcl.StdCtrls;

type

TMyClassX = class

private

FMyName: String;

procedure SetMyName(const Value: String);

public

property MyName: String read FMyName write SetMyName;

end;

//

TForm1 = class(TForm)

Button1: TButton;

Memo1: TMemo;

procedure Button1Click(Sender: TObject);

private

procedure prcMyLog(lText:String);

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.prcMyLog(lText:String);

begin

Memo1.Lines.Add(lText);

Memo1.Lines.Add('');

end;

type

TMyFunction = function: Pointer; // better to scope!

// var

// LMyFunction: TMyFunction = MyFunction; // dont works here! MyFunction is below!

function MyFunction: Pointer; // its ok! now!

begin

Result := nil;

end;

// type

// TMyFunction = function: Pointer; // works too!

var

LMyFunction: TMyFunction = MyFunction; // here is accepted! works likes Global (to down) use for this implementation!

{

function MyFunction: Pointer; // its not OK, because my "var" definition above!

begin

Result := nil;

end;

}

procedure TMyClassX.SetMyName(const Value: String);

begin

FMyName := Value;

end;

procedure TForm1.Button1Click(Sender: TObject);

var

lMyClassX: TMyClassX;

//

LNotifyEvent: TNotifyEvent;

//

// LMyFunction: TMyFunction = MyFunction; // cannot initialize local variables!

//

begin

{ On HELP SYSTEM:

Tests for a "nil" (unassigned) pointer or procedural variable.

Use "Assigned" to determine whether the pointer or the procedure referenced by "P is nil".

"P" must be a "variable reference of a pointer or procedural type".

"Assigned(P)" corresponds to the test "P <> nil" for a "pointer variable",

and "@P <> nil" for a "procedural variable".

"Assigned" returns False if "P is nil", True otherwise.

Tip: When testing object events and procedures for assignment,

you cannot test for "nil", and using "Assigned" is the right way.

}

//

// note that my variables is not explicitly assigned!

//

Memo1.Clear;

//

if Assigned(lMyClassX) then

prcMyLog('lMyClassX is Assigned') { <-- is returning this line, is TRUE }

else

prcMyLog('lMyClassX is Not Assigned');

//

if (lMyClassX <> nil) then

prcMyLog('lMyClassX is Assigned') { <-- is returning this line, is TRUE }

else

prcMyLog('lMyClassX is Not Assigned');

//

// testing my NotifyEvent variable:

//

if Assigned(LNotifyEvent) then

prcMyLog('lMyNotifyEvent is Assigned') { <-- is returning this line, is TRUE }

else

prcMyLog('lMyNotifyEvent is Not Assigned');

//

// --> "LNotifyEvent" dont appears on "Ctrl+Space" for choice (likes "lMyClassX")

// --> but same forcing this expression i have this error:

//

// if (LNotifyEvent <> nil) then --> E2035 Not enought actual parameters ...

// --> F2063 Could not compile used unit "UnitMyClassX.pas"

{ On Help System:

Tip: In particular cases there is a difference between using "Assigned(Something)"

and "Something <> nil".

}

//

// ******************************************************************************

{

For instance, in the following code "Assigned(LMyFunction)" checks whether

the "LMyFunction variable" is "actually assigned",

while "LMyFunction<> nil" tests "the result value of LMyFunction for assignment".

}

if (LMyFunction <> nil) then

prcMyLog('Statement "LMyFunction <> nil"')

else

prcMyLog('Statement "LMyFunction = nil"'); { <-- is returning this line, is FALSE }

//

if Assigned(LMyFunction) then

prcMyLog('Statement "Assigned(LMyFunction)" = true') { <-- is returning this line, is TRUE }

else

prcMyLog('Statement "Assigned(LMyFunction)" = false');

//

{ on Help System:

Note: "Assigned" cannot detect a dangling pointer --that is, "one that is not nil",

but that "no longer points to valid data".

For example, in the code example for "Assigned(SystemAssigned)",

Assigned does "not detect that P is not valid".

}

//

// testing my "Form1" variable"

//

if (Form1 <> nil) then

prcMyLog('Statement "Form1 <> nil"') { <-- is returning this line, is TRUE }

else

prcMyLog('Statement "Form1 = nil"');

//

if Assigned(Form1) then

prcMyLog('Statement "Assigned(Form1)" = true') { <-- is returning this line, is TRUE }

else

prcMyLog('Statement "Assigned(Form1)" = false');

//

//

if (TForm1 <> nil) then

prcMyLog('Statement "TForm1 <> nil"') { <-- is returning this line, is TRUE }

else

prcMyLog('Statement "TForm1 = nil"');

//

(*

if Assigned(TForm1) then // E2036 Variable required --> on compile!

prcMyLog('Statement "Assigned(TForm1)" = true')

else

prcMyLog('Statement "Assigned(TForm1)" = false');

*)

//

end;

end.




hug for all

emailx45


Рег
05 May, 2008

Тем
607

Постов
1273

Баллов
7343
Тем
49554
Комментарии
57426
Опыт
552966

Интересно