Thanks a lot for the code sample.   TypeInfo will be useful, but for now I give 
up this route, because I hope it to be more "elastic" by providing an Append() 
method
if T is an array of something, otherwise no Append() method, this seems can 
only be achieved by inheritance instead of generics.

在 五, 12月 28, 2012 at 7:11 下午,Sven Barth <[email protected]> 写道:
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 = 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 = 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; 
TTestAnsiString = specialize TTest; 
TTestUnicodeString = specialize TTest; 
TTestShortString = specialize TTest; 
TTestBoolean = specialize TTest; 
TTestTTestEnum = specialize TTest; 
TTestTObject = specialize TTest; 
TTestTTestObject = specialize TTest; 

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

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

Reply via email to