none
Dudas sobre utilización de clases en C#

    Question

  • Hola a todos!

    Este es el primer lenguaje de programación orientado a objetos con el que trabajo y tengo algunas dudas con respecto a la utilización de las clases en una aplicación.

    Hasta ahora, intentaba imaginar una clase como un "molde" para crear objetos. Trataba de imaginar la codificación de una clase como si fuera un "super struct" de lenguajes como C, donde además de almacenar variables de distinto tipo (los atributos) puedo utilizar propiedades para controlar qué se puede hacer con los atributos (lectura, escritura o ambos) y que además puede incorporar "funciones" (los métodos de la clase) que pueden operar sobre los atributos de la clase.

    Se que estoy continuamente utilizando las clases y objetos que me proporciona la plataforma .NET, pero el problema es que no tengo muy claro cuando debo crear una clase propia en una aplicación (tampoco tengo muy claro cómo debería diseñar la clase y cómo debería utilizarla en una aplicación, pero supongo que saber cuando utilizarlas me aclararía bastante las ideas)

    Como las aplicaciones que estoy haciendo son bastante sencillas (eso sí, con interfaz gráfica y con acceso a base de datos, pero todo muy sencillito) me da la impresión de que sería matar moscas a cañonazos, pero estoy casi seguro de que esta es una impresión equivocada debido a mi desconocimiento del lenguaje y de los conceptos de POO.

    De momento suelo poner el código de la aplicación en el "cuerpo" de la clase del formulario principal, pero me gustaría replantearme este diseño antes de empezar a codificar la siguiente aplicación.

    Creo que mi principal error es intentar comparar las herramientas que me facilita un lenguaje de programación orientado a objetos con las herramientas de un lenguaje procedural (programación estructurada, vaya).

    Gracias por vuestra atención.

    Un cordial saludo,

    Manuel.

    Thursday, April 05, 2007 7:35 AM

Answers

  • Empieza por planterte cual es el código que usas continuamente en tus programas e intenta reconvertirlo en clases. Por ejemplo; Comentas que accedes habitualmente a datos, y mediante ADO.NET estás efectívamente instanciando clases, pero no definiéndolas.

     

    A nivel de de borrador, cosas como:

     

    A. Ejecutar una consulta.

     

    1. Obtener cadena de conexión del fichero de configuración.

    2. Abrir conexión.

    3. Ejecutar consulta.

    4. Cerrar conexión.

     

    B. Ejecutar un comando.

     

    1. Obtener cadena de conexión del fichero de configuración.

    2. Abrir conexión.

    3. Ejecutar comando.

    4. Cerrar conexión.

     

    La estás definiendo continuamente en tus aplicaciones. Me imagino que este tipo de tareas ya las estás metiendo en funciones del estilo:

     

    1. Función EjecutarConsultaSQL(sentenciaSQLconsulta es cadena) retorno ConjuntoDatos

    2. Función EjecutarComandoSQL(sentenciaSQLcomando es cadena) retorno NumeroFilasAfectadas

     

    Esto es fácilmente reconvertible en una clase al estilo:

     

    Clase AccesoADatosSQL

      EjecutarConsulta(sentenciaSQLconsulta es cadena) retorno ConjuntoDatos

      EjecutarComando(sentenciaSQLcomando es cadena) retorno NumeroFilasAfectadas

    Fin Clase

     

    A la que podemos enriquecer con propiedades del estilo:

     

    TipoBBDD -> SQL Server, Oracle, MySQL, etc...

    TipoAcceso -> Local Remoto

     

    etc..

     

    Puedes ir enriqueciendo las funcionalidades de la clase e ir mejorándola.

     

    Si comentas alguna situación concreta, seguro que te podemos ayudar mejor.

     

    Mi ejemplo no es más que una tonteria muy discutible, pero espero que te sirva de pie.

     

    Un saludo!

    Thursday, April 05, 2007 8:06 AM
  •  Manuel HA Escribió:

    He observado que estaba equivocado en mi enfoque sobre el diseño de una clase...

    A mi se me ocurría crear una clase cliente (por ejemplo) y crear unos métodos para acceder a la base de datos de manera que la llamada a los métodos fuese similar a lo siguiente:

    cliente.Guardar(array de tipo string con los valores de los campos introducidos por usuario)
    cliente.Borrar(clave principal del cliente)
    cliente.Buscar(clave principal del cliente u otros campos)
    etc...

    El caso es que si ahora necesitara crear una nueva clase para productos, tendría que duplicar casi todo el código anterior, de manera que tu solución me parece mucho más elegante y óptima: crear una clase para acceso a base de datos con las operaciones que se realizan con más frecuencia.


    Déjame que te contradiga un poco...  Tú planteamiento no es ni de lejos equivocado (opinión personal), es más considero que es el más adecuado. Esto de la POO no es fácil de encararlo correctamente a la primera, la teoría es fàcil, pero la pràctica nos ofrece muchos caminos distintos y es dificil encontrar la mejor ruta. Tal y como comentas, la opción de encasular toda la lógica y datos de un cliente en una clase, para mí, como "radical" de la POO es algo de vital importancia, pero como ta te comenté, las cosas pasito a pasito, por eso he querido comenzar con el acceso a datos, e intentar no marear a nadie.

     

    Si afianzas la clase de acceso a datos, verás como lo que comentas de duplicar código, no es tan grabe, pq la mayoría de código estará a su vez implementado en otras clases. No se trata de una filosofía u otra, clase de acceso a datos Vs clase de clientes, sino que se trata de complementarlas.

     

    Pese a todo, muchas veces lo que hacemos es de algún modo mapera los campos de lo registros de la tabla clientes en una clase a modo de propiedad, y eso es picar mucho código. Para mí, este planteamniento, es tan necesario como inviable sin herramientas de generación de código como CodeSmith. De lo contrario, para cada cambio de la tabla te vas a volver loco.

     

     Manuel HA Escribió:

    He observado en uno de tus ejemplos que uno de los métodos devuelve un DataSet:

    EjecutarConsulta(sentenciaSQLconsulta es cadena) retorno ConjuntoDatos

    En mi pequeña app no estoy utilizando DataSets, en lugar de eso conecto a la base de datos, ejecuto la sentencia SQL y desconecto de la base de datos. Tal y como comentabas en un mensaje anterior, me parece una forma de trabajar más segura.

    Supongo que devuelves un DataSet en el ejemplo porque es una forma muy cómoda de devolver el resultado de la ejecución de una sentencia, aunque eso implica que desde dónde se llame a ese método se están utilizando DataSets... No haría eso el acceso a BD menos seguro?


    En realidad yo en este caso devolvería un datatable, a no ser que quiera hacer consultas anidadas que me puedan devolver más de un conjunto de datos, en cuyo caso usaría el dataset.

     

    Pero en realidad yo usaría el siguiente esquema:

     

    Obtendría el datareader de clientes, y recorreria todos sus registrsos. Para cada registro crearía un objeto de la clase cliente y copiaría los datos de los campos en las propiedades. Cada nuevo objeto lo añadiría a una lista de objetos, que gestionaria con una clase que denominaría Clientes.

     

    Con lo que a la hora de la verdad, sustituyo el registro por un objeto, y el dataReader por una colección de objetos.

     

    Espero no liarte mucho...

     

     Manuel HA Escribió:

    Algo que no tengo claro es el tema de los "comandos"... ¿Te refieres a INSERT, UPDATE, DELETE y compañia?

     

    Efectívamente. Aunque yo sólo he hecho un borrador. Considerar el tema de los parámetros tb sería importante.

     

    Un saludo!!!

    Thursday, April 05, 2007 9:10 AM
  •  Manuel HA Escribió:
    Si no he entendido mal tu post, creo que la idea sería crear una clase base que implemente los métodos o propiedades comunes a las clases cliente, producto, etc... (¿Sería adecuado/recomendable definir la clase base con el modificador abstract?)

     

    El uso de una clase base es muy útil, pero de momento, en un primer paso es algo complicado. Te recomiendo crear la clase cliente, proveedor, factura, etc. y ya verás como hay mucho código en común, y que poco a poco, irás encapsulando funcionalidad en clases.

     

    Efectíavemente, si finalmente comprendes que elementos te pueden interesar implementar en una clase base, abstract es muy recomendable.

     

    Si te empeñas en lanzarte a la piscina, me resulta prácticamente imposible abordar este tema en toda su complejidad, pero si quieres acabar siendo un "gurú" del tema, que no dudo que algún día lo serás...  Tienes un enlace/libro obligado CSLA.NET (http://www.lhotka.net/Area.aspx?id=4) Este si es gratuito y no tiene desperdicio.

     Manuel HA Escribió:

    De este modo, las subclases (cliente, productos) implementarían por herencia los métodos que comentaba en el post anterior (cliente.Guardar(), cliente.Borrar(), etc) sin tener que codificarlos en cada una de ellas.

     

    De momento, insisto en hacer una primera aproximación implementándolo.

     Manuel HA Escribió:

    En caso de necesidad supongo que sería recomendable que las subclases pudieran redefinir los métodos de la clase base (para alguna situación muy concreta). Nunca lo he hecho, pero imagino que será posible siempre y cuando los modificadores utilizados en la definición de los métodos de la clase base sean los adecuados.


    Microsoft recomienda crear eventos del tipo, antes, durante y después, con posibilidad de cancelar la acción, pero la sobreescritura siempre puede ser útil, sí.

     

     Manuel HA Escribió:

    Respecto a CodeSmith, ha sido todo un descubrimiento. No sabía de la existencia de ese tipo de herramientas, pero la página principal no les funciona y no puedo obtener mucha información del producto. Todo lo que sé es que las últimas versiones son de pago, aunque parece que también existe una versión freeware.

    Por si las moscas, he intentado buscar alternativas libres o gratuitas a CodeSmith. Quizá alguna le resulte de utilidad a los miembros del foro:

    - SmartCode: http://www.codeproject.com/useritems/SmartCode-Code_Generation.asp
    - iCodeGenerator: http://www.icodegenerator.net
    - MyGeneration: http://www.mygenerationsoftware.com
    - CodeAuthor: http://www.codeauthor.org

    Las estudiaré con calma a ver si comprendo bien su funcionamiento y aprendo a utilizarlas.


    La versión gratuita tiene muchas posibilidades, pero de las que comentas, a mí me ha funcionado bastante bien MyGeneration. Las otras no las conozco.

     

     Manuel HA Escribió:

    >> Con lo que a la hora de la verdad, sustituyo el registro por un objeto, y el dataReader por una colección de objetos.

    Creo que comprendo a qué te refieres, pero nunca he trabajado de forma consciente con colecciones de objetos (he utilizado los que están definidos en clases de VS pero nunca he creado y utilizado uno manualmente), de manera que voy a dedicarle un ratito a la lectura a ver si me entero de qué va el tema :-)

    En resumen, lo que creo que propones sería algo de este estilo:

    Campo del registro -> Atributo definido a través de una propiedad
    Registro -> Objeto (instancia de clase)
    Tabla (o DataReader) -> Colección de objetos, instancias de la misma clase

    ¿He comprendido más o menos el asunto?

     

    Lo has comprendido perfectamente!

     

    Un saludo!

    Thursday, April 05, 2007 10:54 AM

All replies

  • Empieza por planterte cual es el código que usas continuamente en tus programas e intenta reconvertirlo en clases. Por ejemplo; Comentas que accedes habitualmente a datos, y mediante ADO.NET estás efectívamente instanciando clases, pero no definiéndolas.

     

    A nivel de de borrador, cosas como:

     

    A. Ejecutar una consulta.

     

    1. Obtener cadena de conexión del fichero de configuración.

    2. Abrir conexión.

    3. Ejecutar consulta.

    4. Cerrar conexión.

     

    B. Ejecutar un comando.

     

    1. Obtener cadena de conexión del fichero de configuración.

    2. Abrir conexión.

    3. Ejecutar comando.

    4. Cerrar conexión.

     

    La estás definiendo continuamente en tus aplicaciones. Me imagino que este tipo de tareas ya las estás metiendo en funciones del estilo:

     

    1. Función EjecutarConsultaSQL(sentenciaSQLconsulta es cadena) retorno ConjuntoDatos

    2. Función EjecutarComandoSQL(sentenciaSQLcomando es cadena) retorno NumeroFilasAfectadas

     

    Esto es fácilmente reconvertible en una clase al estilo:

     

    Clase AccesoADatosSQL

      EjecutarConsulta(sentenciaSQLconsulta es cadena) retorno ConjuntoDatos

      EjecutarComando(sentenciaSQLcomando es cadena) retorno NumeroFilasAfectadas

    Fin Clase

     

    A la que podemos enriquecer con propiedades del estilo:

     

    TipoBBDD -> SQL Server, Oracle, MySQL, etc...

    TipoAcceso -> Local Remoto

     

    etc..

     

    Puedes ir enriqueciendo las funcionalidades de la clase e ir mejorándola.

     

    Si comentas alguna situación concreta, seguro que te podemos ayudar mejor.

     

    Mi ejemplo no es más que una tonteria muy discutible, pero espero que te sirva de pie.

     

    Un saludo!

    Thursday, April 05, 2007 8:06 AM
  • Muchas gracias por tu respuesta Toni, me ha aclarado muchos conceptos.

    Decirte que de momento, en la aplicación que comentábamos el otro día para PocketPC, he seguido tu consejo y no me he modificado la estructura del programa para poder centrarme mejor en el funcionamiento del acceso a base de datos (que estoy haciendo manualmente) y no marearme con otras cosas.

    No recuerdo si lo llegué a comentar, pero de momento estas aplicaciones son de prueba, para ir pillándole el tranquillo al lenguaje, pero seguramente en breve tendré entre manos algo más serio y complejo (aún no me han dado detalles) y de ahí mi inquietud por el diseño.

    He observado que estaba equivocado en mi enfoque sobre el diseño de una clase...

    A mi se me ocurría crear una clase cliente (por ejemplo) y crear unos métodos para acceder a la base de datos de manera que la llamada a los métodos fuese similar a lo siguiente:

    cliente.Guardar(array de tipo string con los valores de los campos introducidos por usuario)
    cliente.Borrar(clave principal del cliente)
    cliente.Buscar(clave principal del cliente u otros campos)
    etc...

    El caso es que si ahora necesitara crear una nueva clase para productos, tendría que duplicar casi todo el código anterior, de manera que tu solución me parece mucho más elegante y óptima: crear una clase para acceso a base de datos con las operaciones que se realizan con más frecuencia.

    He observado en uno de tus ejemplos que uno de los métodos devuelve un DataSet:

    EjecutarConsulta(sentenciaSQLconsulta es cadena) retorno ConjuntoDatos

    En mi pequeña app no estoy utilizando DataSets, en lugar de eso conecto a la base de datos, ejecuto la sentencia SQL y desconecto de la base de datos. Tal y como comentabas en un mensaje anterior, me parece una forma de trabajar más segura.

    Supongo que devuelves un DataSet en el ejemplo porque es una forma muy cómoda de devolver el resultado de la ejecución de una sentencia, aunque eso implica que desde dónde se llame a ese método se están utilizando DataSets... No haría eso el acceso a BD menos seguro?

    Algo que no tengo claro es el tema de los "comandos"... ¿Te refieres a INSERT, UPDATE, DELETE y compañia?

    Gracias una vez más por tu ayuda! :-)

    Un cordial saludo,

    Manuel.
    Thursday, April 05, 2007 8:43 AM
  •  Manuel HA Escribió:

    He observado que estaba equivocado en mi enfoque sobre el diseño de una clase...

    A mi se me ocurría crear una clase cliente (por ejemplo) y crear unos métodos para acceder a la base de datos de manera que la llamada a los métodos fuese similar a lo siguiente:

    cliente.Guardar(array de tipo string con los valores de los campos introducidos por usuario)
    cliente.Borrar(clave principal del cliente)
    cliente.Buscar(clave principal del cliente u otros campos)
    etc...

    El caso es que si ahora necesitara crear una nueva clase para productos, tendría que duplicar casi todo el código anterior, de manera que tu solución me parece mucho más elegante y óptima: crear una clase para acceso a base de datos con las operaciones que se realizan con más frecuencia.


    Déjame que te contradiga un poco...  Tú planteamiento no es ni de lejos equivocado (opinión personal), es más considero que es el más adecuado. Esto de la POO no es fácil de encararlo correctamente a la primera, la teoría es fàcil, pero la pràctica nos ofrece muchos caminos distintos y es dificil encontrar la mejor ruta. Tal y como comentas, la opción de encasular toda la lógica y datos de un cliente en una clase, para mí, como "radical" de la POO es algo de vital importancia, pero como ta te comenté, las cosas pasito a pasito, por eso he querido comenzar con el acceso a datos, e intentar no marear a nadie.

     

    Si afianzas la clase de acceso a datos, verás como lo que comentas de duplicar código, no es tan grabe, pq la mayoría de código estará a su vez implementado en otras clases. No se trata de una filosofía u otra, clase de acceso a datos Vs clase de clientes, sino que se trata de complementarlas.

     

    Pese a todo, muchas veces lo que hacemos es de algún modo mapera los campos de lo registros de la tabla clientes en una clase a modo de propiedad, y eso es picar mucho código. Para mí, este planteamniento, es tan necesario como inviable sin herramientas de generación de código como CodeSmith. De lo contrario, para cada cambio de la tabla te vas a volver loco.

     

     Manuel HA Escribió:

    He observado en uno de tus ejemplos que uno de los métodos devuelve un DataSet:

    EjecutarConsulta(sentenciaSQLconsulta es cadena) retorno ConjuntoDatos

    En mi pequeña app no estoy utilizando DataSets, en lugar de eso conecto a la base de datos, ejecuto la sentencia SQL y desconecto de la base de datos. Tal y como comentabas en un mensaje anterior, me parece una forma de trabajar más segura.

    Supongo que devuelves un DataSet en el ejemplo porque es una forma muy cómoda de devolver el resultado de la ejecución de una sentencia, aunque eso implica que desde dónde se llame a ese método se están utilizando DataSets... No haría eso el acceso a BD menos seguro?


    En realidad yo en este caso devolvería un datatable, a no ser que quiera hacer consultas anidadas que me puedan devolver más de un conjunto de datos, en cuyo caso usaría el dataset.

     

    Pero en realidad yo usaría el siguiente esquema:

     

    Obtendría el datareader de clientes, y recorreria todos sus registrsos. Para cada registro crearía un objeto de la clase cliente y copiaría los datos de los campos en las propiedades. Cada nuevo objeto lo añadiría a una lista de objetos, que gestionaria con una clase que denominaría Clientes.

     

    Con lo que a la hora de la verdad, sustituyo el registro por un objeto, y el dataReader por una colección de objetos.

     

    Espero no liarte mucho...

     

     Manuel HA Escribió:

    Algo que no tengo claro es el tema de los "comandos"... ¿Te refieres a INSERT, UPDATE, DELETE y compañia?

     

    Efectívamente. Aunque yo sólo he hecho un borrador. Considerar el tema de los parámetros tb sería importante.

     

    Un saludo!!!

    Thursday, April 05, 2007 9:10 AM
  • Como siempre, gracias por tu rápida respuesta, Toni! :-)

    Si no he entendido mal tu post, creo que la idea sería crear una clase base que implemente los métodos o propiedades comunes a las clases cliente, producto, etc... (¿Sería adecuado/recomendable definir la clase base con el modificador abstract?)

    De este modo, las subclases (cliente, productos) implementarían por herencia los métodos que comentaba en el post anterior (cliente.Guardar(), cliente.Borrar(), etc) sin tener que codificarlos en cada una de ellas.

    En caso de necesidad supongo que sería recomendable que las subclases pudieran redefinir los métodos de la clase base (para alguna situación muy concreta). Nunca lo he hecho, pero imagino que será posible siempre y cuando los modificadores utilizados en la definición de los métodos de la clase base sean los adecuados.

    Respecto a CodeSmith, ha sido todo un descubrimiento. No sabía de la existencia de ese tipo de herramientas, pero la página principal no les funciona y no puedo obtener mucha información del producto. Todo lo que sé es que las últimas versiones son de pago, aunque parece que también existe una versión freeware.

    Por si las moscas, he intentado buscar alternativas libres o gratuitas a CodeSmith. Quizá alguna le resulte de utilidad a los miembros del foro:

    - SmartCode: http://www.codeproject.com/useritems/SmartCode-Code_Generation.asp
    - iCodeGenerator: http://www.icodegenerator.net
    - MyGeneration: http://www.mygenerationsoftware.com
    - CodeAuthor: http://www.codeauthor.org

    Las estudiaré con calma a ver si comprendo bien su funcionamiento y aprendo a utilizarlas.

    >> Con lo que a la hora de la verdad, sustituyo el registro por un objeto, y el dataReader por una colección de objetos.

    Creo que comprendo a qué te refieres, pero nunca he trabajado de forma consciente con colecciones de objetos (he utilizado los que están definidos en clases de VS pero nunca he creado y utilizado uno manualmente), de manera que voy a dedicarle un ratito a la lectura a ver si me entero de qué va el tema :-)

    En resumen, lo que creo que propones sería algo de este estilo:

    Campo del registro -> Atributo definido a través de una propiedad
    Registro -> Objeto (instancia de clase)
    Tabla (o DataReader) -> Colección de objetos, instancias de la misma clase

    ¿He comprendido más o menos el asunto?

    De nuevo, muchísimas gracias por tu ayuda! :-)

    Un cordial saludo,

    Manuel.

    Thursday, April 05, 2007 10:36 AM
  •  Manuel HA Escribió:
    Si no he entendido mal tu post, creo que la idea sería crear una clase base que implemente los métodos o propiedades comunes a las clases cliente, producto, etc... (¿Sería adecuado/recomendable definir la clase base con el modificador abstract?)

     

    El uso de una clase base es muy útil, pero de momento, en un primer paso es algo complicado. Te recomiendo crear la clase cliente, proveedor, factura, etc. y ya verás como hay mucho código en común, y que poco a poco, irás encapsulando funcionalidad en clases.

     

    Efectíavemente, si finalmente comprendes que elementos te pueden interesar implementar en una clase base, abstract es muy recomendable.

     

    Si te empeñas en lanzarte a la piscina, me resulta prácticamente imposible abordar este tema en toda su complejidad, pero si quieres acabar siendo un "gurú" del tema, que no dudo que algún día lo serás...  Tienes un enlace/libro obligado CSLA.NET (http://www.lhotka.net/Area.aspx?id=4) Este si es gratuito y no tiene desperdicio.

     Manuel HA Escribió:

    De este modo, las subclases (cliente, productos) implementarían por herencia los métodos que comentaba en el post anterior (cliente.Guardar(), cliente.Borrar(), etc) sin tener que codificarlos en cada una de ellas.

     

    De momento, insisto en hacer una primera aproximación implementándolo.

     Manuel HA Escribió:

    En caso de necesidad supongo que sería recomendable que las subclases pudieran redefinir los métodos de la clase base (para alguna situación muy concreta). Nunca lo he hecho, pero imagino que será posible siempre y cuando los modificadores utilizados en la definición de los métodos de la clase base sean los adecuados.


    Microsoft recomienda crear eventos del tipo, antes, durante y después, con posibilidad de cancelar la acción, pero la sobreescritura siempre puede ser útil, sí.

     

     Manuel HA Escribió:

    Respecto a CodeSmith, ha sido todo un descubrimiento. No sabía de la existencia de ese tipo de herramientas, pero la página principal no les funciona y no puedo obtener mucha información del producto. Todo lo que sé es que las últimas versiones son de pago, aunque parece que también existe una versión freeware.

    Por si las moscas, he intentado buscar alternativas libres o gratuitas a CodeSmith. Quizá alguna le resulte de utilidad a los miembros del foro:

    - SmartCode: http://www.codeproject.com/useritems/SmartCode-Code_Generation.asp
    - iCodeGenerator: http://www.icodegenerator.net
    - MyGeneration: http://www.mygenerationsoftware.com
    - CodeAuthor: http://www.codeauthor.org

    Las estudiaré con calma a ver si comprendo bien su funcionamiento y aprendo a utilizarlas.


    La versión gratuita tiene muchas posibilidades, pero de las que comentas, a mí me ha funcionado bastante bien MyGeneration. Las otras no las conozco.

     

     Manuel HA Escribió:

    >> Con lo que a la hora de la verdad, sustituyo el registro por un objeto, y el dataReader por una colección de objetos.

    Creo que comprendo a qué te refieres, pero nunca he trabajado de forma consciente con colecciones de objetos (he utilizado los que están definidos en clases de VS pero nunca he creado y utilizado uno manualmente), de manera que voy a dedicarle un ratito a la lectura a ver si me entero de qué va el tema :-)

    En resumen, lo que creo que propones sería algo de este estilo:

    Campo del registro -> Atributo definido a través de una propiedad
    Registro -> Objeto (instancia de clase)
    Tabla (o DataReader) -> Colección de objetos, instancias de la misma clase

    ¿He comprendido más o menos el asunto?

     

    Lo has comprendido perfectamente!

     

    Un saludo!

    Thursday, April 05, 2007 10:54 AM
  • Estupendo Toni, gracias tanto por tus explicaciones como por tus comentarios :-)

    Espero seguir aprendiendo mientras el coco dé de sí!

    Lo cierto es que eres una ayuda increíble... No veas lo duro que se hacía no tener a nadie con quien comentar las dudas "existenciales" de este mundillo (tal y como tú decías, muchos caminos y posibilidades, pero ¿Cómo saber el correcto?)

    Sé que no hay una solución perfecta, pero ayuda mucho saber que vas en la dirección correcta desde el punto de vista de alguien con mucha más experiencia. Muy agradecido!

    Un cordial saludo,

    Manuel.

    Thursday, April 05, 2007 11:13 AM
  • JajajajaJaja!!

     

    Me voy a poner rojo!

     

    Aquí estamos para intentar ayudarnos entre todos.

     

    Es un placer!

    Thursday, April 05, 2007 12:39 PM