if Assigned(my) then
Caption := my.StringValue
else
Caption := '"my" not assigned';
The "my" is an object instance of some class, defined as "var my : TMySimpleObject", that could have been declared as:
type TMySimpleObject = class
private
fStringValue: string;
public
property StringValue : string read fStringValue write fStringValue;
end;
The TMySimpleObject class defines a string property called "StringValue" using a private fStringValue field to write and/or read the value of the StringValue property.
If "my" object, in the example above, is not assigned and you try to access (read) its StringValue property, you will receive an Access Violation.
From my point of view, sometimes it takes to much time (lines of code) to always check if the object is assigned or not, to read its properties, and not receive access violations.
How aout simply reading my.StringValue, without the need to check if the object is nil?
Property Getters to the Rescue
With the next declaration, using property getter method, you do not need to care if an object is nil, or better to say, you would test for nil in the getter of the property: type TMyObject = class(TMySimpleObject)
private
fStringProp : string;
function GetStringProp: string;
public
property StringProp : string read GetStringProp;
end;
....
function TMyObject.GetStringProp: string;
begin
if Assigned(Self) then
result := fStringProp
else
result := 'my object is nil';
end;
With the above implementation of the StringProp property, you are safe to read the value of the property even when the instance of the TMyObject class is nil (not assigned):
Caption := my.StringProp
No need for:
if Assigned(my) then
Caption := my.StringProp
else
Caption := '"my" not assigned';
Note that the getter method, GetStringProp, checks if the instance is assigned. If "Self" is not assignend, a default value is returned - in the above example: "my object is nil".
Using a getter method you can save lines of code - check if the instance is assigned in the property getter and not where you actually need the value of the property!
If Self = nil, simply return something that for you is a "default value" for non instantiated instances of a class.
Such a trick could not be used to write values to properties - as obviously for writing you need a class instance that is not nil.
In my applications I do have various classes that only expose read only properties, where their vaues are set using an overriden construtor.
What If You Need to Access Properties That Are Objects?
Here's a more complex example: type TMyObjectEx = class(TMyObject)
private
type TMySubObject = class
private
fMySubIntValue : integer;
function GetMySubIntValue: integer;
public
property MySubIntValue : integer read GetMySubIntValue;
end;
private
fSubObject: TMySubObject;
function GetSubObject: TMySubObject;
public
destructor Destroy; override;
property SubObject : TMySubObject read GetSubObject;
end;
The TMyObjectEx extends TMyObject by including an object type property, using a sub class named "TMySubObject".
Again, we want to be able to read the MySubIntValue property value (integer). The MySubIntValue is a property of TMySubObject which is exposed as a read only property of the TMyObjectEx class.
Here's the implementation of the GetMySubIntValue getter:
function TMyObjectEx.TMySubObject.GetMySubIntValue: integer;
begin
if Assigned(Self) then
result := fMySubIntValue
else
result := -1; //default value for non assigned objects
end;
function TMyObjectEx.GetSubObject: TMySubObject;
begin
if Assigned(Self) then
begin
if fSubObject = nil then fSubObject := TMyObjectEx.TMySubObject.Create;
result := fSubObject;
end
else
result := nil;
end;
destructor TMyObjectEx.Destroy;
begin
FreeAndNil(fSubObject);
inherited;
end;
With the above declaration, you can ask for the value of "my.SubObject.MySubIntValue" even if "my" is NIL!
Therefore, the next line will not raise an access violation EVEN if "my" is NIL!
Caption := my.StringProp + IntToStr(my.SubObject.MySubIntValue);
Im not sure if it is "OOP-OK" to use the presented way of reading properties for non assigned objects - but I do use it and I'm happy not to always need to check if some object is assigned or not.
Of course, in some scenarioos you MUST check if an object is nil, but for some, the above idea would come handy :)


