views:

350

answers:

3

Since my question from yesterday was perhaps not completely clear and I did not get the answer I wanted, I will try to formulate it in a more general way:

Is there a way to implement special behaviour based on the actual type of an instantiated generic type either using explict conditional statements or using some kind of specialization? Pseudocode:

TGenericType <T> = class
  function Func : Integer;
end;
...
function TGenericType <T>.Func : Integer;
begin
  if (T = String) then Exit (0);
  if (T is class) then Exit (1);
end;
...
function TGenericType <T : class>.Func : Integer;
begin
Result := 1;
end;
function TGenericType <String>.Func : Integer;
begin
Result := 0;
end;
+1  A: 

in C#, you can do a typeof(T) which would allow you to do something like (T = String) or (T is class)

I havent seen your other question (you didnt link to it), but what are you really looking for? In general, doing something conditional on type or a typecode via ifs like you are doing or a switch is generally best transformed into having an interface or abstract function somewhere that gets customised by context.

Ruben Bartelink
I added the link to the other question. Basically I want some rough estimate for the size in bytes. I want to treat strings different than other types.
Smasher
Whoever downvoted this, feel free to comment on your reasons. I think it was a reasonable answer
Smasher
Ah, ye olde SO karma system sometimes pleasantly surprises, thanks! Amusingly, 'twas me that upvoted your reply-to-self (but didnt upvote the question initially :P)
Ruben Bartelink
+7  A: 

You can fall back to RTTI, by using TypeInfo(T) = TypeInfo(string). To test to see if something is a class, you could use something like PTypeInfo(TypeInfo(T))^.Kind = tkClass.

The PTypeInfo type and tkClass enumeration member are defined in the TypInfo unit.

Barry Kelly
+1 Thanks a lot! That does exactly what I was looking for! Even if you're not a fan of my original idea ;)
Smasher
+2  A: 

If someone is interested how I did implement my "worst-case size with special treatment for strings"

class function RTTIUtils.GetDeepSize <T> (Variable : T) : Integer;
var
  StringLength          : Integer;
  Ptr                   : PInteger;
begin
if (TypeInfo (T) = TypeInfo (String)) then
  begin
  Ptr := @Variable;
  Ptr := PInteger (Ptr^);
  Dec (Ptr);
  StringLength := Ptr^;
  Result := StringLength * SizeOf (Char) + 12;
  end
else
  Result := 0;
end;

For me, this does the job at hand. Thanks to all contributors!

Smasher