Is there a way to create an equivalent to C# get/set in Ada ?
I have a type like this (in Ada) :
-- Ada :
type MyType is record
Value : Integer;
end record;
I want to split the value like this
-- Ada :
type MyType is record
ten : Integer;
unit : Integer;
end record;
But I want to keep MyType.Value
(referenced in many readonly files). I want to create an accessor but I did not find how to do in Ada. I know how to do in C# :
// C# :
int Value
{
get
{
return this.ten * 10 + this.unit;
}
set
{
this.unit = value % 10;
this.ten = value / 10;
}
}
What I want to do :
-- ada :
MyType var := MyType'(Value => 15); -- unmodified code
var.Value := 65; -- can be modified like before
Integer ten := var.ten; -- new getter
As I said in the comment of my answer to your previous question, There's no language construct that does it for you. Depending on your use-case, you could possibly employ controlled types:
type MyTypeView (Data : not null access MyType) is limited
new Ada.Finalization.Limited_Controlled with record
Value: Integer;
end record;
overriding procedure Initialize (Object : in out MyTypeView) is
begin
Object.Value := Object.Data.ten * 10 + Object.Data.unit;
end Initialize;
overriding procedure Finalize (Object : in out MyTypeView) is
begin
Object.Data.ten := Object.Value / 10;
Object.Data.unit := Object.Value mod 10;
end Finalize;
This would allow you to alter the Value in the way you want with the View:
declare
-- assuming MyObj is an object of type MyType
View : MyTypeView (MyObj'Access);
-- Initialize will be called, setting View.Value
begin
-- can access value as "property"
Do_Something (View.Value);
-- can assign value as "property"
View.Value := 123;
-- when View goes out of scope, Finalize will be called, updating MyObj
end;
Note however that as long as View lives, View.Value is detached from the original object, meaning that at the end;
, other modifications of MyObj that happened after View has been created will be discarded. In a single-threaded program, this means that you may not call any subroutines that may instantiate a View of the same object while the current view lives (and may not directly instantiate a second View of this object inside the block).