Putting the generic in Generics?

Putting the generic in Generics?

Annoyance 1: 
  TThing = class
  private
    FThing: T;
    procedure SetThing(const Value: T);
  protected
    property Thing: T read FThing write SetThing;
  public
    procedure Configure(const aThing:T = nil); // *
  end;

* [dcc32 Error]: E2268 Parameters of this type cannot have default values
Why? It's a class instance pointer, isn't it?

Annoyance 2:
Types are simplified.
 
Unit 1
TAbstractColumn = class end;

TColumn = class(TAbstractItem) end;

TGridHelper = class(TList>) end;

Unit 2 (uses 1)
TQueryGridHelper = class(TGridHelper) end;

TQueryStrGridHelper = class(TQueryGridHelper);
TQueryDBGridHelper = class(TQueryGridHelper);

note: TDBAdvGrid is a direct descendent of TAdvStringGrid

Unit 3 (uses 1 and 2)
procedure SomeClass.DefineColumns(const aHelper: ???);

If it is defined as 
procedure DefineColumns (const Helper: TQueryStrGridHelper);
I get: [dcc32 Error]: E2010 Incompatible types: 'TQueryStrGridHelper' and 'TQueryDBGridHelper' - which is understandable, but how can I specify an argument type for DefineColums which can take both a TQueryStrGridHelper and a  TQueryDBGridHelper?

Comments

  1. Re #1, what happens if you write "procedure Configure(const aThing:T = Default(T));"?

    ReplyDelete
  2. David Millington Doesn't work because the error is not "this particular default value does not work" but "generic type cannot have default value at all"

    ReplyDelete
  3. procedure SomeClass.DefineColumns(const aHelper: TQueryGridHelper)

    Also: I smell generics overusage/abuse.

    ReplyDelete
  4. Stefan Glienke We are using these grids by the dozen.  They are filled from three different kinds of sources, and we have a lot of scaffolding code that needs to be streamlined.  Abuse? Not sure. Overusage - well, it's either that - or repeating the same code in dozens and dozens of places.

    It's not the first time I've had a similar problem with Generics.  Polymorphism is not trivial with generics if you are unable to have a type-parameterless abstract class as root.

    ReplyDelete
  5. Generics are not to solve polymorphism, that is already solved by OOP. And OOP also already solved only having to writing code once when doing something for a class hierarchy.

    ReplyDelete
  6. OOP where the polymorphic variance is based on Generic type T variation makes it difficult to create a root type for the polymorphic hierarchy - because you need methods in the root class which have parameters or results of type T which is not present in the abstract root class.  

    Without an untyped root class - I can't create procedures that take any descendant of the root class without further type specifiers. 

    In this case, T can be a specific object class from our hierarchy - or a RecordSet from a query, or a record.

    There is one way around it - and that is to pass parameters as typeless and do a cast in the override.  Not my favorite way of doing things.

    ReplyDelete
  7. I am talking about putting the grid class as generic parameter which I am sure is unnecessary (I have seen similar code at work where people overused generics and increased the code complexity exponentially).

    ReplyDelete

Post a Comment