Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing the type of a generic in delphi

I want some way to write a function in delphi like the following

procedure Foo<T>;
begin
    if T = String then
    begin
        //Do something
    end;

    if T = Double then
    begin
        //Do something else
    end;
end;

ie: I want to be able to do different things based on a generic type

I've tried using TypeInfo in System but this seems to be suited to objects rather than generic types.

I'm not even sure this is possible in pascal

like image 430
sav Avatar asked Jun 25 '15 06:06

sav


People also ask

What is generic data type?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.

What is generic type arguments?

The generic argument list is a comma-separated list of type arguments. A type argument is the name of an actual concrete type that replaces a corresponding type parameter in the generic parameter clause of a generic type. The result is a specialized version of that generic type.

Is generic type information present at runtime?

Is generic type information present at runtime? Generic type information is not present at runtime. C. You cannot create an instance using a generic class type parameter.


2 Answers

TypeInfo should work:

type
  TTest = class
    class procedure Foo<T>;
  end;

class procedure TTest.Foo<T>;
begin
  if TypeInfo(T) = TypeInfo(string) then
    Writeln('string')
  else if TypeInfo(T) = TypeInfo(Double) then
    Writeln('Double')
  else
    Writeln(PTypeInfo(TypeInfo(T))^.Name);
end;

procedure Main;
begin
  TTest.Foo<string>;
  TTest.Foo<Double>;
  TTest.Foo<Single>;
end;
like image 66
Ondrej Kelle Avatar answered Sep 29 '22 03:09

Ondrej Kelle


From XE7 onwards you can use GetTypeKind to find the type kind:

case GetTypeKind(T) of
tkUString:
  ....
tkFloat:
  ....
....
end;

Of course tkFloat identifies all floating point types so you might also test SizeOf(T) = SizeOf(double).

Older versions of Delphi do not have the GetTypeKind intrinsic and you have to use PTypeInfo(TypeInfo(T)).Kind instead. The advantage of GetTypeKind is that the compiler is able to evaluate it and optimise away branches that can be proven not to be selected.

All of this rather defeats the purpose of generics though and one wonders if your problem has a better solution.

like image 26
David Heffernan Avatar answered Sep 29 '22 03:09

David Heffernan