Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a read-only property?

Tags:

delphi

I am using a TMS object inspector at run time, but assume my question would be equally valid for Delphi at design time.

I want to have a property which can be set programically (at run time) or hard coded (at design time). It should be visible to the user as the information is useful to him and it should be changeable at run-time by the program but not by the user via the object inspector.

I tried

published property FileName : String read FFileName;

and the property is visible, but it is also changeable in the object inspector (and throws a read of address zer0 exception when changed) :-(

like image 625
Mawg says reinstate Monica Avatar asked Apr 21 '11 02:04

Mawg says reinstate Monica


People also ask

What is read only property?

Read only means that we can access the value of a property but we can't assign a value to it. When a property does not have a set accessor then it is a read only property. For example in the person class we have a Gender property that has only a get accessor and doesn't have a set accessor.

How can you make a property write only?

You can use WriteOnly only at module level. This means the declaration context for a WriteOnly property must be a class, structure, or module, and cannot be a source file, namespace, or procedure. You can declare a property as WriteOnly , but not a variable.

How do I make a Python property read only?

If you need to make a read-only attribute in Python, you can turn your attribute into a property that delegates to an attribute with almost the same name, but with an underscore prefixed before the its name to note that it's private convention.


1 Answers

This looks like a perfectly valid and correct read-only property

published property FileName : String read FFileName;

if you add an extra property that public and thus only settable during runtime you're in business:

public property RuntimeFilename: string read FFileName write FFilename;
//note that two properties, one published and one public point to the same field.

However if you want to hack it and get rid of the exception in Design-time
change it to:

//Only writable during runtime.
private
  procedure SetFileName(Value: string);
published
  property FileName: string read FFileName write SetFileName;

....
procedure TMyClass.SetFileName(Value: string);
begin
  if csDesigning in Componentstate then {do nothing}
  else FFileName:= Value;
end;

What I think might also be going on...

Disconnect between designtime and runtime code
In order to change the runtime behaviour of the code you need only change the source code and remove the write ... part of the property.

This will not effect the design-time code though, for that you need to reinstall the component.
If you change the source code of a registered component and you keep the changes within the private, protected and/or public sections of the component you are usually OK.

However if you change the published part of a component and you do not reinstall that component you will have abnormal behaviour at startup.

This is because in design-time you are still working with the old/unchanged binary versions of the component. This version has not had the write part removed and allows you to change the underlying string FFilename.

Come runtime the init-code will read the form resource 1) and spots a value to be written to FFilename. However the procedure SetFilename is no longer available and therefore a access violation occurs during program startup.

1) (the data that was in the .dfm file and is now stored inside a dfm resource in your .exe)

like image 73
Johan Avatar answered Oct 10 '22 13:10

Johan