views:

417

answers:

4

Hi

How can I create a generic class only containing primitive types?

TField<T: xxx> = class  
private
    FValue: T;  
public  
    property Value: T read FValue write FValue;  
end;

I don't need interfaces, classes, etc, I only want booleans, ints, floats and so on...

Or there is another way to do that?

Thanks

A: 

If you want to limit the types that can be used for your generic can't you just check for valid types in the creation?

birger
+1  A: 

I'm not sure whether I'm getting your question right, but if you want a variable that can hold different primitive data types you might have a look at the Variant data type.

You would not need generics for that ;-)

Mef
Delphi 2010, as part of its RTTI improvements, introduced the TValue in the Rtti unit, which is essentially a more light-weight Variant. It might be slightly better for your purpose - assuming you're using D2010, of course.
Michael Madsen
Actually, some of the Variant conversions depend on the run-time environment (regional settings, etc), so they can get you some very unexpected results.
Jeroen Pluimers
@Michael: +1 comment for mentioning TValue
Jeroen Pluimers
Yes I'am using D2010, I don't have any specific purpose, I'm just playing as deep as my brain let me with generics...
Leffy
+1  A: 

According to Craig Stuntz' blog

The Delphi/Win32 type system isn’t rooted (built-in simple types, records, and classes don’t have a common ancestor), and primitive types can’t/don’t implement interfaces

so most likely you cannot restrict a generic class to primitive types (as opposed to C# which allows a "where T: struct")

devio
-1: you can; use the 'record' restriction that DanB mentions.
Jeroen Pluimers
+4  A: 

You can use the "record" keyword, to constrain to value types (not reference types):

TField<T: record> = class   
private 
    FValue: T;   
public   
    property Value: T read FValue write FValue;   
end;
DanB
+1 for mentioning the 'record' keyword, as it one of the most intuitive usages of keywords in the Delphi language.
Jeroen Pluimers
Note even though the 'record' keyword limits it to value types, you hardly can use the values at all. Just look at the hoops Allen Bauer needed to go through to just implement the Equal and NotEqual operators for Nullable<T> in this article: http://blogs.embarcadero.com/abauer/2008/09/18/38869
Jeroen Pluimers
Its funny, you cannot do things like:-<T: boolean> //even if is silly...-<T: TObject> //you can put any class inheriting from TObject, but not TObject itselfWhat about if I want to make a generic object pool for parameterless contructor objects?TObjectPool<T: TObject, constructor>I get "E2510 Type 'TObject' is not a valid constraint"
Leffy
Leffy: indeed strange. I wanted to constrain to all .create-able types and ran into the same thing
Marco van de Voort
Found it, use "class" instead of tobject
Marco van de Voort