SITUATION
I have written a class for second degree equations that looks like this. You can find here the full code of the class but it's not very relevant for the question.
type
TArrayOfDouble = array of array of double;
type
TEqSecGrado = class
private
//variables
a, b, c: double;
delta: double;
solutions: TArrayOfDouble;
solRealCount: integer;
solImaginaryCount: integer;
class var currentIstances: integer;
class var totalIstances: integer;
//methods
function getDelta(const vala, valb, valc: double): double; overload;
public
constructor Create(const a, b, c: double);
destructor Destroy; override;
//methods
function getDelta: double; overload;
function getSolutions: TArrayOfDouble; virtual;
//properties
property valueOfA: double read a;
property valueOfB: double read b;
property valueOfC: double read c;
property realSolutionsCount: integer read solRealCount;
property imaginarySolutionsCount: integer read solImaginaryCount;
class property currentEquationsCount: integer read currentIstances;
class property totalEquationsCount: integer read totalIstances;
end;
I thought to create a new type called TArrayOfDouble
that will contain the solution of my equation. In the main form I use the class in this way:
procedure TForm3.Button1Click(Sender: TObject);
var solver: TEqSecGrado;
soluzioni: TArrayOfDouble;
begin
//f(x) = 3x^2 - x - 2 -> [sol.1 = 1 | sol.2 = -0,666666666666667]
solver := TEqSecGrado.Create(3,-1,-2);
try
soluzioni := solver.getSolutions;
//soluzioni[0][0] = 1; soluzioni[0][1] = 0;
//soluzioni[1][0] = -0,666666666666667; soluzioni[1][1] = 0;
finally
solver.Free;
end;
end;
Now I have the results inside soluzioni
and I can output them. (I have used a matrix because in the first spot I put real solutions, in this case 1 and -0.67, and in the second sport immaginary solutions if needed).
QUESTION
When I output the solutions I want to convert them into a fraction. I wanted to do something like soluzioni[a][b].toFraction
. So I thought I could use a record helper for double.
type
TSupport = record helper for Double
function toFraction: string;
function toString: string; //I have added this LATER
end;
Here I come with my doubt. Once I have created the TSupport
and the toFraction
method, I was able to call soluzioni[0][0].toFraction but I couldn't call soluzioni[i][0].toString.
To solve my problem I decided to add the function toString and everything worked. Does the record helper hide all the other methods? If I removed the record helper instead, I can use again the toString method as always.
I know that helpers are a way to extend a class without using inheritance, but why can I use only the methods I've declared in my helper?
A limitation of class and record helpers is that only one can be active at once. The ToString
method of Double
is actually implemented in a record helper provided by the Delphi RTL. Once you attach your helper to the type, then the RTL helper is no longer active.
The documentation says:
You can define and associate multiple helpers with a single type. However, only zero or one helper applies in any specific location in source code. The helper defined in the nearest scope will apply. Class or record helper scope is determined in the normal Delphi fashion (for example, right to left in the unit's uses clause).
This is a long standing issue which Embarcadero has known about ever since helpers were introduced. In many long years they have not addressed the issue and with the best will in the world I think you should assume that they never will.
So, you have two choices:
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