Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-10-2015
doctorhd doctorhd is offline
Miembro
NULL
 
Registrado: abr 2013
Posts: 48
Poder: 0
doctorhd Va por buen camino
Tipos Genericos

Hola a todos tengo en siguiente problema: Cree una clase que acepta un parámetro de tipo genérico <T>, la idea de este parámetro es que acepte clases que descienden de una clase en común, lo cual también podría definirse de este tipo <t:class>, para acotar su definición. El problema que tengo es como acceder a los campos que tiene el parámetro <T>, ya que este representa la clase que es pasada. Para que quede mas claro detallo el código:
Código Delphi [-]
{Clase base que puede ser pasada como parámetro genérico a TField}
type
    TDomain = class
    private
      FName:String;
      FTipoSQL:TFieldType;
      FLenFieldIn:Integer;
      FLenFieldOut:Integer;
    protected
      constructor Create(const AName:String; ATipoSQL:TFieldType; ALenFieldIn:Integer; ALenFieldOut:Integer);
    public
      destructor Destroy; override;
    public
      property Name:String read FName;
      property TipoSQL:TFieldType read FTipoSQL;
      property LenFieldIn:Integer read FLenFieldIn;
      property LenFieldOut:Integer read FLenFieldOut;
    end;

{Clase que recibe el parámetro de tipo genérico}
type
    TField(T:class,constructor)= class
    private
      FNameField:String;
      FNameIn:String;
      FNameOut:String;
      FDomain:T;
    private
      function getNamesIn(const Index:Integer):String;
      function getNamesOut(const Index:Integer):String;
      function SepararCadena(const Cadena: string; const Delim: Char): TStringList;
      procedure setDomain(ADomain:T);
    protected
      constructor Create(const ANameField:String; ANameIn:String; ANameOut:String; ADomain:T);
    public
      destructor Destroy; override;
    public
      property NameField: String read FNameField;
      property NameIn: String read FNameIn;
      property NameOut: String read FNameOut;
      property NamesIn[const Index: Integer]:String read getNamesIn;
      property NamesOut[const Index: Integer]:String read getNamesOut;
      property Domain:T read FDomain;
    end;


{Procedimiento en donde necesito acceder a los campos de la clase que es pasada como parámetro}
procedure TField(T.setDomain)(ADomain:T);
begin
  {Creamos el objeto Domain o sus descendientes}
  FDomain:=T(GetTypeData(PTypeInfo(TypeInfo(T)))^.ClassType.Create);

  {Aqui el problema, el compilador no reconoce los campos}
  FDomain.FTipoSQL:=ADomain.TipoSQL;
  FDomain.FLenFieldIn:=ADomain.LenFieldIn;
  FDomain.FLenFieldOut:=ADomain.LenFieldOut;
end;{procedure}
Como ven la clase recibe un parámetro <T> que es asignado a FDomain. Esta asignación necesito hacerla campo a campo (clonar el objeto). Me imagino que el compilador al no saber que tipo de parámetro sera pasado no admite especificar sus campos en forma literal, pero debe existir alguna forma de invocarlos....

nota:Cambie <> por (), ya que las etiquetas de código Delphi no lo muestran.

Saludos...
Responder Con Cita
  #2  
Antiguo 06-10-2015
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.059
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por doctorhd Ver Mensaje
nota:Cambie <> por (), ya que las etiquetas de código Delphi no lo muestran.
Sí, es un bug, pero puedes poner un espacio entre ellos y ya se verán bien.
Responder Con Cita
  #3  
Antiguo 06-10-2015
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Una de las razones por las que no terminan de gustarme las generics (o templates, como las llaman en C++) es que confunde al programador. Como en este caso.

Si lo que quieres es que un procedimiento, función o variable admita o use objetos que deriven de cierta clase, entonces no debes usar generics, sino herencia. Basta con indicar la clase base y admitirá cualquier objeto cuya clase derive de dicha clase base. No sólo podrás discriminar qué clases usar, sino que además generará ejecutables más ligeros.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #4  
Antiguo 06-10-2015
doctorhd doctorhd is offline
Miembro
NULL
 
Registrado: abr 2013
Posts: 48
Poder: 0
doctorhd Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Sí, es un bug, pero puedes poner un espacio entre ellos y ya se verán bien.


Cita:
Empezado por Ñuño Martínez Ver Mensaje
no debes usar generics, sino herencia.
Ya lo había pensado, pero (siempre hay un pero), cuando accedes al campo (FDomain) desde fuera de la clase, solo tendrás acceso a los integrantes de la clase base (TDomain) en forma directa. Si quieres tener acceso a los integrantes de la clase descendiente tendrás que especificarlo en forma explicita, por ejemplo:
Código Delphi [-]
TDomainString(FDomain).MiCampo;
Suponiendo que TDomainString es descendiente de TDomain. La idea es que dicho acceso sea transparente:
Código Delphi [-]
FDomain.MiCampo;
Saludos...
Responder Con Cita
  #5  
Antiguo 06-10-2015
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.913
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Accediendo una propiedad privada como si fuera una publica? Uno de los conceptos fundamentales de la OO es el *encapsulamiento*. Estas yendo contra el viento y por eso sufres.

Y la forma que pones de ver domain es absurda.

Casi siempre un programador se pone a dar vueltas a una aparente restriccion tecnica es porque su diseño esta deficiente. Osea: Hacks son un code-smell (una indicacion poderosa, 90% de los casos, que estas contra el viento, en vez de solucionando un genuino problema)
__________________
El malabarista.
Responder Con Cita
  #6  
Antiguo 06-10-2015
doctorhd doctorhd is offline
Miembro
NULL
 
Registrado: abr 2013
Posts: 48
Poder: 0
doctorhd Va por buen camino
Cita:
Accediendo una propiedad privada como si fuera una publica?
Eso es un error de escritura de mi parte los correcto era hacer alusión a Domain.
Cita:
Y la forma que pones de ver domain es absurda.
...???
Responder Con Cita
  #7  
Antiguo 06-10-2015
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.913
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Cita:
Empezado por mamcx Ver Mensaje
Y la forma que pones de ver domain es absurda.
Ok, podrias explicar que es lo que estas tratando de hacer? Cual es el objetivo de este codigo?
__________________
El malabarista.
Responder Con Cita
  #8  
Antiguo 06-10-2015
elrayo76 elrayo76 is offline
Miembro
 
Registrado: ene 2004
Ubicación: En la tierra, por eso mis archivos en la tierra y no en la nuebe...
Posts: 291
Poder: 21
elrayo76 Va por buen camino
Podrías explicar que quieres haer con el código que pones?

Saludos
__________________
Si tienes una función o procedimiento con diez parámetros, probablemente hayas olvidado uno
Responder Con Cita
  #9  
Antiguo 06-10-2015
Avatar de Caminante
Caminante Caminante is offline
Miembro
 
Registrado: oct 2010
Ubicación: Lima - Peru
Posts: 338
Poder: 14
Caminante Va camino a la fama
Cita:
Empezado por doctorhd Ver Mensaje
...la idea de este parámetro es que acepte clases que descienden de una clase en común...
Hola

Puedes crear una referencia de clase como campo en tu clase generica.

Me explico.

En lazarus cree una clase que representa una lista generica a objectos (TClientes, TArticulos, etc). Para eso defini un campo privado

Código Delphi [-]
Private
FTipoClass=TBaseClass;

Que esta definido asi:

Código Delphi [-]
TBaseClass=Class of TClaseBase;

En el codigo para crear los objectos de la lista hago asi

Código Delphi [-]
ItemList:=FTipoClass.create;

Claro que de todas formas es necesario hacer un cast para obtener la clase que deseo

Código Delphi [-]
MiCLiente:=TCliente(Items[1]).UnMetodo

Espero sea de utilidad

Saludos
__________________
Caminante, son tus huellas el camino y nada más; Caminante, no hay camino, se hace camino al andar.
Antonio Machado
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Class Helpers sobre Genericos.. yapt OOP 1 24-04-2011 16:06:17
Procedures Genericos con Parametros de Controles.... Kenobi Varios 23 21-11-2007 00:42:41
Listbox con items genericos ANG4L Varios 2 11-05-2006 03:54:37
Parametros sql genericos AbcXxx Conexión con bases de datos 2 10-11-2005 00:31:59
... 100 tipos... Jure Humor 0 18-03-2004 14:24:30


La franja horaria es GMT +2. Ahora son las 07:08:58.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi