On 28.12.2012 00:58, xrfang wrote:
Hi,

Suppose I have a generic class like this:

type
   TSerie = generic class
   public
     procedure Append(value: T);
   end

It should be "generic TSerie<T> = class".


then, in the Append procedure can I do something like:

case *typeof*(T) of
   integer: // do something with integer
   string: // do someting with string
   ... ...
end;

Don't use "TypeOf". The function you are looking for is called "TypeInfo" and works with every type, except Enums with jumps (e.g. TTestEnum = (teOne := 1, teTwo := 5)).

Here you have an example:

=== source begin ===

program tgentypes;

{$mode objfpc}

uses
  typinfo;

type
  generic TTest<T> = class
    class procedure DoSomething(aArg: T);
  end;

{ TTestClass }

class procedure TTest.DoSomething(aArg: T);
var
  ti: PTypeInfo;
begin
  ti := TypeInfo(aArg);
  case ti^.Kind of
    tkInteger:
      Writeln('Type is an integer');
    tkAString:
      Writeln('Type is an AnsiString');
    tkUString:
      Writeln('Type is a UnicodeString');
    tkBool:
      Writeln('Type is a Boolean');
    tkEnumeration:
      Writeln('Type is an enumeration');
    tkSString:
      Writeln('Type is a ShortString');
    tkClass:
      Writeln('Type is a class');
    tkObject:
      Writeln('Type is an object');
    else
      Writeln('Unhandled type: ', ti^.Kind);
  end;
end;

type
  TTestEnum = (teOne, teTwo, teThree);
  TTestObject = object

  end;

  TTestLongInt = specialize TTest<LongInt>;
  TTestAnsiString = specialize TTest<AnsiString>;
  TTestUnicodeString = specialize TTest<UnicodeString>;
  TTestShortString = specialize TTest<ShortString>;
  TTestBoolean = specialize TTest<Boolean>;
  TTestTTestEnum = specialize TTest<TTestEnum>;
  TTestTObject = specialize TTest<TObject>;
  TTestTTestObject = specialize TTest<TTestObject>;

var
  obj: TObject;
  testobj: TTestObject;
begin
  TTestLongInt.DoSomething(42);
  TTestAnsiString.DoSomething('Hello World');
  TTestUnicodeString.DoSomething('Hello World');
  TTestShortString.DoSomething('Hello World');
  TTestBoolean.DoSomething(True);
  TTestTTestEnum.DoSomething(teOne);
  TTestTObject.DoSomething(obj);
  TTestTTestObject.DoSomething(testobj);
end.

=== source end ===

For getting the exact value of the argument you need to rely on the information provided by the RTTI as you can't use e.g. "IntToStr(aArg)" in case of an integer as you'll get a compiler error when you specialize the class with something that is not an Integer.

Regards,
Sven


--
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to