I am curious about, what is the equivalent of final tag in delphi :
public final int stackoverflow;
I use
class var
tag but class var equals static variable. But final is different from them.
A Java final variable can be initialized once only. This initialization can be made by an initialization statement, or by an assignment statement.
As such there is not equivalent in Delphi. There is nothing that allows you to restrict a variable to being initialized no more than one time. The closest equivalent would be a constant, declared with const. This would restrict you to making the initialization in the const declaration.
There is nothing comparable shipped with delphi.
But you can achieve this with a record
unit FinalType;
interface
uses
System.SysUtils;
type
Final<T> = record
private
FIsInitialized: string;
FValue: T;
public
class operator implicit( const a: T ): Final<T>;
class operator implicit( const a: Final<T> ): T;
end;
implementation
{ Final<T> }
class operator Final<T>.implicit( const a: T ): Final<T>;
begin
if Result.FIsInitialized <> ''
then
raise Exception.Create( 'Fehlermeldung' );
Result.FIsInitialized := '*';
Result.FValue := a;
end;
class operator Final<T>.implicit( const a: Final<T> ): T;
begin
if a.FIsInitialized = ''
then
Result := default ( T )
else
Result := a.FValue;
end;
end.
program FinalCheck;
uses
FinalType;
var
MyFinalValue : Final<Integer>;
procedure OutputValue( AValue : Integer );
begin
WriteLn( 'Value: ', AValue );
end;
begin
MyFinalValue := 10; // everything is ok
OutputValue( MyFinalValue );
MyFinalValue := 12; // <- Exception
OutputValue( MyFinalValue );
end.
UPDATE
There is one side effect you cannot catch:
program FinalCheck;
uses
FinalType;
var
MyFinalValue : Final<Integer>;
procedure SetFinalValue( AValue : Integer );
var
LNewValue : Final<Integer>;
begin
LNewValue := AValue;
MyFinalValue := LNewValue;
end;
begin
MyFinalValue := 10; // everything is ok
SetFinalValue( 12 ); // no exception!!!
end.
In most cases I see this as a public ReadOnly field of a class. In Delphi you would use a public readonly property instead, but you have to take care, that the value is not changed from inside the class. The final flag ist just a guard, that you cannot change the value from inside.
This is a class with a final - but it is only final with the comment and if you respect this
TFoo = class
private
// Please do not change this value once it is set
FStackoverflow : Integer;
public
property Stackoverflow : Integer read FStackoverflow;
end;
Or with the record
TFoo = class
public
Stackoverflow : Final<Integer>;
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With