Skip to content

Generics, Commas, and Semicolons

In Delphi 2009, you declare a generic type with multiple type parameters by separating the type parameters with a semicolon. If the type parameters have a constraint, you separate the constraint using a colon. Like this:

type
  TFoo<TypeParam1; TypeParam2: ISomething> = class

This means that TypeParam2 must support ISomething. In C#, you would use where instead of the colon syntax.

To use (as opposed to declare) a generic type, however, you separate the type parameters with commas, like this:

  Foo := TFoo<integer, TBar>.Create;

Does that seem a little odd? It might to a C# programmer, I guess. But it should look very familiar to a Delphi programmer, because it exactly mirrors the syntax for procedure arguments:

  // declare:
  procedure Foo(ArgA: integer; ArgB: boolean);
  // invoke:
  Foo(A, B);

Indeed, the only reason this is really worth mentioning at all is that if you forget and you use a comma instead of a semicolon when declaring a list of type parameters in a generic type declaration, the message you get from the compiler is not especially helpful.

{ 7 } Comments

  1. Baalbaki | February 17, 2009 at 8:13 am | Permalink

    Really confused…
    Can any one describe to us how we can use it in the real world?
    a very simple scenario would be great.
    thanks

  2. Craig Stuntz | February 17, 2009 at 8:22 am | Permalink

    "It?" You mean generics?

    I have given lots of examples of generics on this blog, such as this one. If you have read all of those examples and there is still something specific that you don’t understand, then you should clarify the question.

    In general, you should not expect more effort in a response to a question than you put into asking the question in the first place.

  3. Rudy Velthuis | February 18, 2009 at 2:32 pm | Permalink

    The following is valid too:

    TFoo = class<TypeParam1, TypeParam2: ISomething>

    But this means that both type params have the same constraint, ISomething. This is in analogy to

    procedure Foo(Param1, Param2: ISomething);

    Now if there are multiple type params, and all are unconstrained, you can use commas as well as semicolons:

    TBar<K; Y>

    or

    TBar<K, Y>

    are the same. But I would say that, in a declaration, it is best to always use semicolons to separate type parameters, to avoid complications if you want to add constraints at a later date.

  4. Craig Stuntz | February 18, 2009 at 2:45 pm | Permalink

    Rudy, that is valid, indeed, but has different meaning in the code I posted. In your case, TypeParam1 has to support ISomething. In my case, it does not.

  5. Rudy Velthuis | February 25, 2009 at 3:09 pm | Permalink

    > In your case, TypeParamone has to support ISomething. In my case, it does not.

    I was aware of that. I was merely explaining that ; ought to be the normal way of separating them when you are DECLARING parametric types, and that the comma is actually meant to give two parametric types the same constraint(s), just like ; is required to separate parameters in a function parameter list, and that the comma is used to give two parameters the same type. Of course, if you don’t define any constraints anyway, it doesn’t matter whether you use ; or , . I still think it is safer to ALWAYS use ; unless you want to give them the same constraints.

    My comment got a little mixed up. I already said that using the comma would give both parametric types the same constraint, but the < and > were seen as HTML tags so the generic parts got missing.

  6. Surendran Bangalore | February 5, 2010 at 3:41 am | Permalink

    One question in Delphi 2010, the help section mentions only commas (not semi colons) at the declaration section I am pasting the link and code section also.

    Am I missing anything? Could you please explain reg. the discrepancy?

    Response: Because the comma and the semicolon mean different things. Read Rudy’s comment above (plus the discussions which follow); does that explain it for you?

    Delphi 2010 help section
    =================
    ms-help://embarcadero.rs2010/rad/Overview_of_Generics.html

    Code Example
    ==========
    type
    TPair= class<TKey; TValue> // declares TPair type with two type parameters

    private
    FKey: TKey;
    FValue: TValue;
    public
    function GetKey: TKey;
    procedure SetKey(Key: TKey);
    function GetValue: TValue;
    procedure SetValue(Value: TValue);
    property Key: TKey read GetKey write SetKey;
    property Value: TValue read GetValue write SetValue;
    end;

    type
    TSIPair = TPair; // declares instantiated type
    TSSPair = TPair; // declares with other data types
    TISPair = TPair;
    TIIPair = TPair;
    TSXPair = TPair;

  7. Surendran Bangalore | February 5, 2010 at 3:46 am | Permalink

    With reg. to my post above.

    I think, the angle brackets (for generics code my my pasted code) is being removed while rendering html (I mean I pasted the full code but found that the "" are not coming.
    Pasting the line again below,

    "TPair= class // declares TPair type with two type parameters"

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 713 access attempts in the last 7 days.

Close