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?
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.