6

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

4 Answers 4

7

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;
Sign up to request clarification or add additional context in comments.

5 Comments

+1 for mentioning the 'record' keyword, as it one of the most intuitive usages of keywords in the Delphi language.
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: blogs.embarcadero.com/abauer/2008/09/18/38869
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 itself What 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: indeed strange. I wanted to constrain to all .create-able types and ran into the same thing
Found it, use "class" instead of tobject
1

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 ;-)

4 Comments

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.
Actually, some of the Variant conversions depend on the run-time environment (regional settings, etc), so they can get you some very unexpected results.
@Michael: +1 comment for mentioning TValue
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...
1

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")

1 Comment

-1: you can; use the 'record' restriction that DanB mentions.
0

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?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.