Recent

Author Topic: returning a generic type  (Read 4806 times)

JorgeAldo

  • New Member
  • *
  • Posts: 11
returning a generic type
« on: April 21, 2015, 05:53:47 am »
Is it possible to make a generic type return a value with the same type as itself ?

This is the code :

Code: [Select]
Generic GCustomActorMessage<ContainedType> = Class(TCustomActorMessage)
Private
fValue : ContainedType;
Public
Function CanBeCloned : Boolean; Override;
Function Clone : GCustomActorMessage<ContainedType>; OVerride;
Published
Property Value : ContainedType Read fValue Write fValue;
End;

What i need is that the function clone return a new instance of the object being specialized, with the same type as it (instead of TCustomActorMessage).

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: returning a generic type
« Reply #1 on: April 21, 2015, 10:18:42 am »
Using a Type declaration inside the class:

Code: [Select]
  tbwimagegen <T > = Class(TBaseImage)
                 Type
                    TLocalType =tbwimagegen <T>;
                    TLocalTypeClass = Class Of TLocalType;             
                 public
                       function Clone(into:TLocalTypeClass=Nil): TLocalType;
                     end;

For a discussion about the argument of Clone see http://stackoverflow.com/questions/4041760/correct-way-to-duplicate-delphi-object/4041906#4041906

JorgeAldo

  • New Member
  • *
  • Posts: 11
Re: returning a generic type
« Reply #2 on: April 21, 2015, 05:17:06 pm »
How can i make a generic class factory ?

Cant make this generic class factory work.

Code: [Select]
{
  This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.
   
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
}

// Copyright (c) 2010 2011 2012 2013 2014 2015 - J. Aldo G. de Freitas Junior

{$mode objfpc}
{$H+}{$M+}

Unit
GenericClassFactory;

Interface

Uses
{$ifdef unix}
cthreads,
cmem,
{$endif}
SysUtils,
Contnrs,
RTTIObjects;

Type
EGenericClassFactory = Class(Exception);

Generic GGenericClassFactory<ObjectType> = Class
Type
TGenericType = ObjectType;
TGenericTypeClass = Class Of TGenericType;
Private
fMutex : TMultiReadExclusiveWriteSynchronizer;
fHashTable : TFPHashList;
Public
Constructor Create;
Destructor Destroy; Override;
Procedure Register(Const aClass : TClass; Const aName : String = '');
Function Build(Const aName : String): TGenericType;
End;

Implementation

Constructor GGenericClassFactory.Create;
Begin
Inherited;
fMutex := TMultiReadExclusiveWriteSynchronizer.Create;
fHashTable := TFPHashList.Create;
End;

Destructor GGenericClassFactory.Destroy;
Begin
FreeAndNil(fMutex);
FreeAndNil(fHashTable);
Inherited;
End;

Procedure GGenericClassFactory.Register(Const aClass : TClass; Const aName : String = '');
Begin
Try
fMutex.BeginWrite;
If aName = '' Then
fHashTable.Add(aClass.ClassName, Pointer(aClass))
Else
fHashTable.Add(aName, aClass);
Finally
fMutex.EndWrite;
End;
End;

Function GGenericClassFactory.Build(Const aName : String): TGenericType;
Var
lIndex : Integer;
Begin
Try
fMutex.BeginRead;
lIndex := fHashTable.FindIndexOf(aName);
If lIndex >= 0 Then
Begin
Build := TGenericTypeClass(fHashTable.Items[lIndex]).Create;
End
Else
Raise EGenericClassFactory.Create('Type ' + aName + ' is not registered in this class factory.');
Finally
fMutex.EndRead;
End;
End;

End.
« Last Edit: April 21, 2015, 07:36:43 pm by JorgeAldo »

dubst3pp4

  • Jr. Member
  • **
  • Posts: 86
  • Retro computing ~ GNU/Linux
    • me on Mastodon
Re: returning a generic type
« Reply #3 on: February 22, 2019, 04:15:55 pm »
Using a Type declaration inside the class:

Code: [Select]
  tbwimagegen <T > = Class(TBaseImage)
                 Type
                    TLocalType =tbwimagegen <T>;
                    TLocalTypeClass = Class Of TLocalType;             
                 public
                       function Clone(into:TLocalTypeClass=Nil): TLocalType;
                     end;

For a discussion about the argument of Clone see http://stackoverflow.com/questions/4041760/correct-way-to-duplicate-delphi-object/4041906#4041906

Although this topic is some years old, for the sake of completeness I think the type TLocalType must be a specialization of tbwimagegen:

Code: Pascal  [Select][+][-]
  1. Type
  2.   TLocalType = specialize tbwimagegen <T>;
  3.   TLocalTypeClass = Class Of TLocalType;  
  4.  
Jabber: xmpp:marc.hanisch@member.fsf.org -- Support the Free Software Foundation: https://my.fsf.org/donate

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: returning a generic type
« Reply #4 on: February 22, 2019, 04:48:17 pm »
Since it is {$mode delphi} code, I doubt it :-)

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: returning a generic type
« Reply #5 on: February 22, 2019, 05:10:27 pm »
It would probably also needs a type limiter to make any sense at all, like:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. Type
  3.   tbwimagegen <T:class, constructor > = Class(TBaseImage)
  4.  end;
  5.   TLocalType =  tbwimagegen <T:class, constructor>;
  6.   TLocalTypeClass = Class Of TLocalType;  
« Last Edit: February 22, 2019, 05:12:26 pm by Thaddy »
Specialize a type, not a var.

 

TinyPortal © 2005-2018