Class Methods vs Instance Methods

9

C# implements BigInteger.Parse as a static class method, and there is obvious reason for it: you can call a static class methods in a variable’s declaration:

  BigInteger N = BigInteger.Parse(stringToParse);

Delphi/Pascal does not support the above syntax, so the equivalent code is

var
  N: BigInteger;
begin
  N:= BigInteger.Parse(stringToParse);

But now it looks like implementing BigInteger.Parse as a static class method is nothing but additional typing; using an instance method looks better:

var
  N: BigInteger;
begin
  N.Parse(stringToParse);

So, what is the right “Delphi way” of implementing BigInteger.Parse – as a static class method or as an instance method?

Advertisements

Static specifier and overriding class methods

9

I’ve encountered an interesting problem while overriding virtual class method. Consider the next program:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TBase = class
    class function GetName: string; virtual;
    class procedure Test; static;
  end;

  TChild = class(TBase)
    class function GetName: string; override;
  end;

class function TBase.GetName: string;
begin
  Result:= 'TBase';
end;

class procedure TBase.Test;
begin
  Writeln(GetName);
end;

class function TChild.GetName: string;
begin
  Result:= 'TChild';
end;

begin
  TBase.Test;
  TChild.Test;
  Readln;
end.

Despite the GetName function is overridden in TChild class the output is
StaticBug

The bug is static specifier of the TBase.Test method. After the specifier is removed the output is as expected:
StaticOut

The reason of the above compiler behavior is clear – with static specifier in TBase.Test method declaration the compiler (Delphi XE was used) receives no class information and statically binds TBase.GetName class method. The bad thing is that the compiler is silent about the problem and issues no warning.