How to draw a generic type into an actual type in Delphi

Consider the following code

procedure TMyClass.SetParam<T>(Name: string; Value: T);
begin
  if (TypeInfo(T) = TypeInfo(string)) then
  begin
    FHashTable.AddString(Name, (Value as string));
  end
  else if (TypeInfo(T) = TypeInfo(Integer)) then
  begin
    FHashTable.AddInteger(Name, (Value as Integer));
  end
......

I want to have a general procedure that gets a generic value of type T and inserts the value into the hash table according to the actual type of T.

The compiler will not allow me to do this cast, nor will it allow me to do something like Integer (Value).

Can someone explain how can I implement the above?

+4
source share
2 answers

Although you can easily do this with classes, it is not so simple with other types such as integers, strings, and enumerations. Although they work with generics to some extent, they are small. On the other hand, in this case you do not need.

, , ( , ). , , , .

unit UnitTest1;

interface

type
  THashTable = class
    procedure AddString( const pName : string; pValue : string ); virtual; abstract;  // dummy for illustration only
    procedure AddInt( const pName : string; const pInt : integer ); virtual; abstract;  // dummy for illustration only
  end;

  TMyClass = class
  private
    FHashTable : THashTable;
  public
    procedure TestString;
    procedure TestInt;

    procedure SetParam( const pName : string; const pValue : string ); overload;
    procedure SetParam( const pName : string; const pValue : integer ); overload;

  end;

implementation

{ TMyClass }

procedure TMyClass.SetParam(const pName, pValue: string);
begin
  FHashTable.AddString( pName, pValue );
end;

procedure TMyClass.SetParam(const pName: string; const pValue: integer);
begin
  FHashTable.AddInt( pName, pValue );
end;

procedure TMyClass.TestInt;
begin
  SetParam( 'Int', 4 );
end;

procedure TMyClass.TestString;
begin
  SetParam( 'Int', 'Fred' );
end;

end.

THashTable , FHashTable. . , , , .

+4

- :

procedure TMyClass.SetParam<T>(Name: string; Value: T);
begin
  if (TypeInfo(T) = TypeInfo(string)) then
  begin
    FHashTable.AddString(Name, PString(@Value)^);
  end
  else if (TypeInfo(T) = TypeInfo(Integer)) then
  begin
    FHashTable.AddInteger(Name, PInteger(@Value)^);
  end
......

:

uses
  System.Rtti;

procedure TMyClass.SetParam<T>(Name: string; Value: T);
var
  LValue: TValue;
begin
  LValue := TValue.From<T>(Value);
  if (TypeInfo(T) = TypeInfo(string)) then
  begin
    FHashTable.AddString(Name, LValue.AsString);
  end
  else if (TypeInfo(T) = TypeInfo(Integer)) then
  begin
    FHashTable.AddInteger(Name, LValue.AsInteger);
  end
......
+4

Source: https://habr.com/ru/post/1665695/


All Articles