Edijs Kolesnikovičs
Edijs Kolesnikovičs

Reputation: 1695

Generic type name and value

I have a Generic factory. I want to get the type name and its value as a string, eg:

An enumeration TTV with a value of Samsung would return 'TTV.Samsung'.

A string with a value of 'stackoverflow' would return 'string.stackoverflow'.

An integer with a value of 10 would return 'integer.10'.

A TValue made from TTV.Samsung (eg TValue.From(TTV.Samsung)) would return 'TTV.Samsung'.

Here is my function declaration:

function TGenericFactory<TKey>.GetTypeString(Key: TKey): string;

How do I make this work?

Upvotes: 1

Views: 162

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 598001

TValue has a ToString() method that handles the bulk of this work for you, so you can have your function create a temp TValue from any input value and then use TValue.ToString() to convert the value to a string regardless of what type it actually is. You can use RTTI to get the input value's type name. In the case where the input value is a TValue, you can use the RTTI of the type that the TValue is holding.

uses
  System.Rtti;

type
  TGenericFactory<TKey> = class
  public
    class function GetTypeString(Key: TKey): string;
  end;

function TValueToString(const V: TValue): string; inline;
begin
  Result := String(V.TypeInfo.Name) + '.' + V.ToString;
end;

class function TGenericFactory<TKey>.GetTypeString(Key: TKey): string;
type
  PTValue = ^TValue;
begin
  if TypeInfo(TKey) = TypeInfo(TValue) then
    Result := TValueToString(PTValue(@Key)^)
  else
    Result := TValueToString(TValue.From<TKey>(Key));
end;

Here are the results:

type
  TTV = (Nokia, Samsung, Motorola);

var
  S: String;
begin
  S := TGenericFactory<TTV>.GetTypeString(TTV.Samsung);
  // returns 'TTV.Samsung'

  S := TGenericFactory<String>.GetTypeString('stackoverflow');
  // returns 'string.stackoverflow'

  S := TGenericFactory<Integer>.GetTypeString(10);
  // returns 'Integer.stackoverflow'

  S := TGenericFactory<TValue>.GetTypeString(TValue.From(TTV.Samsung));
  // returns 'TTV.Samsung'
end.

Upvotes: 2

Related Questions