elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Duda carga de objetos POO
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Duda carga de objetos POO  (Leído 979 veces)
Devilkeeper

Desconectado Desconectado

Mensajes: 12


Ver Perfil
Duda carga de objetos POO
« en: 8 Enero 2018, 21:35 »

Hola compañeros:

Estoy retomando la Programación Orientada a Objetos, y conociendo ya las bases y demás, me surje una duda a la hora de encarar un proyecto.

Imaginemos que tengo una empresa con distintos puestos, cada uno de los cuales trabaja con unas referencias, que se almacenan en unas estanterías, y cada puesto cuenta con sus propios empleados.

La cosa es, si yo cargo un objeto del puesto 1, ¿debería cargar todos los objetos relacionados?. Si mi clase Puesto tiene un campo que es una lista de objetos tipo Referencias, ¿al cargar el puesto 1 debería cargar en esa lista todas las Referencias de ese puesto?. Y lo mismo para el resto de cosas, si la clase Puesto tiene un campo que es una lista de trabajadores... ¿Tendría que cargar la lista de trabajadores, cargando a su vez los posibles objetos relacionados de la clase Trabajador?. Direcciones por ejemplo.

No sé si es una manera correcta de trabajar, o es mejor cargar los Puestos y según necesite ir cargando y descargando las listas. Si quisiera cargar todos los puestos, tendría en memoría muchísimos datos, y no sé si eso está bien.

Gracias.


En línea

NEBIRE


Desconectado Desconectado

Mensajes: 2.328


Ver Perfil
Re: Duda carga de objetos POO
« Respuesta #1 en: 9 Enero 2018, 01:31 »

No importa lo complejo de un sistema, la cuestión es que solo se 'carga' lo que se necesita usar. Por ello el diseño debe ser eficiente.

Las dependencias deben ser realistas... si es objetiva y realmente dependiente, se hace dependiente, si no, no.

Una rueda tiene atributos, como numero de radios, diámetro, ancho, número de tornillos, marca, etc... luego es razonable que todos esos atributos sean propiedades de las ruedas. Luego la cargar una rueda (crearla, referenciarla) todos sus atributos estarán disponibles. Y todo vehículo tiene una cierta cantidad de ruedas, luego las ruedas será algún tipo de colección, que tienen todos los vehículos, pero que cada implementación de vehículo tiene un valor diferente. Sin embargo si cambias una rueda, deberá del mismo tamaño que el resto, esto es debe encajar... así que debiera haber constructores específicos para cada tipo de vehículo.

Piensa con cosas cotidianas, manejables que puedas fácilmente entender el porqué de ello.
Un simple ejemplo:

Código:
Interfaz Vehículo
    atributo clase Motor
    atributo coleccion Ruedas
    atributo coleccion Puertas

    atributo Motorizado
    atributo TienePuertas
    atributo Velocidad
    atributo EstaEnMarcha
    atributo NumeroRuedas
    atributo VelocidadMaxima
    atributo Color

     metodo Acelerar
     metodo Frenar
     metodo Parar
     metodo Arrancar
Fin interfaz
Una interfaz (es una clase que) define una plantilla básica y que luego cada implementación puede particularizar.


Código:
Clase Bicicleta Implementa Vehículo
    atributo clase Motor
        Read = Nada
        Mensaje "El vehículo bicicleta no tiene motor"
    fin atributo

    atributo coleccion Ruedas
        Read(i)
            Si ((i=0) ó (i=1)) luego
                Devolver Ruedas(i)
            Sino
                Mensaje "El vehículo bicicleta solo tiene 2 ruedas, no puede proporcionarse la rueda" + i.Tostring
            fin si
        fin Read
    fin atributo

    atributo coleccion Puertas
        Read = Nada
        Mensaje "El vehículo bicicleta no tiene puertas"
    fin atributo

    atributo Motorizado
        Read = p_Motorizado
    fin atributo

    atributo TienePuertas
        Read = p_TienePuertas
    fin atributo

    atributo Velocidad
        Read = p_Velocidad
    fin atributo

    atributo EstaEnMarcha
        Read = p_EstaEnMarcha // ó: (p_velocidad>0)
    fin atributo

    atributo NumeroRuedas
        Read = p_NumeroRuedas
    fin atributo

    atributo VelocidadMaxima
         Read = p_VelocidadMaxima
    fin atributo

    atributo Color
        Read
            devolver p_Color
        fin read
        Write (c)
            p_color = c   
         fin write
    fin atributo


    metodo Acelerar
        Si (p_velocidad = 0) luego p_EnMarcha = TRUE
        p_velocidad +=1
     fin metodo

     metodo Frenar
        Si (p_Velocidad >0) luego
            p_Velocidad -=1
            Si (p_Velocidad = 0) luego p_EnMarcha = FALSE
        fin si
    fin metodo

    metodo Parar
        p_Velocidad = 0
        p_EnMarcha = FALSE
    fin metodo

    metodo Arrancar
        Si (p_EnMarcha = FALSE) luego
            p_Velocidad = 20  //por ejemplo...
            p_EnMarcha = TRUE
        fin si
    fin metodo

     metodo Nueva(color)  // Crear
         p_VelocidadMaxima = 65
         p_NumeroRuedas = 2
         p_Motorizado = FALSE
         p_TienePuertas = FALSE

         p_Color = Color

         Ruedas = nueva coleccion
         r = nueva Rueda(diametro=650, radios=50, ancho=5, ...etc..)
         r.Situacion = Delantera
         Ruedas.añadir(r)

         r = nueva Rueda(diametro=650, radios=50, ancho=5, ...etc..)
         r.Situacion = Trasera
         Ruedas.añadir(r)
   
       
         ...etc...
     fin metodo

     atributo NumeroDePiñones
     atributo NumeroDePlatos
fin clase

Como se puede ver algo simple, pero fácil de entender y seguir el ejemplo... tiene varios atributos de solo lectura, y tan solo el color es lectura y escritura. Como es una bicie, no tiene motor ni puertas, además fuera de la interfaz que implementa se han añadido dos atributos aparte, NúmeroDePiñones y NumeroDePlatos... faltaría a la interfaz un método 'cambiarDeMarcha' y añadir un atributo 'NumeroDeMarchas'... la bicileta también tiene...

Como ves cuando se 'carga' un vehículo, con él se carga todo lo necesario, porque forma un 'objeto', todo englobado en la clase, un único objeto engloba a todo, pero puede estar formado por varios objetos, un motor podría ser otro objeto en sí mismo, lo mismo que las ruedas y las puertas... básicamente cualquier cosa que sea más compleja que una mera propiedad. Fíjate como aunque no hemos definido una clase Rueda, al crearla sin embargo le estamos pasando algunos atributos necesarios para crearla, y tras ello, incluso modificamos un atributo (donde está situada la rueda), que no se incluye en el 'constructor'... en cambio al crear el objeto bicicleta, solo se reclama el atributo color, el número de ruedas es prefijado por el diseño propio de la bici, lo mismo sucede con 'motorizado' y 'tienepuertas'.  Un diseño mejor sería tener un atributo llamado NumeroDePuertas, en sustitución de 'TienePuertas', ya que 'número identifica cuantas son, y al caso '0', es lo mismo que 'no tiene'. Es decir una primera aproximación se define y luego de repensarlo haces cambios y ajustes...

Como ves no es necesario cargar nada más que lo que respecta al vehículo... pero eso está en su propio diseño. si ahora creas un objeto ciudad, tendrás por un lado objetos calle, objetos edificios y objetos vehículos, incluso objetos garaje.
Cada uno de ellos sería una colección, pero incluso así, una ciudad tendría atributos como 'nombre', 'extension', 'ubicacion', etc... pero es necesario cargar todos los vehículos de la ciudad?... No, tan solo los de la calle actual.
Siendo calles una colección de la clase 'Calle', y poseyendo cada calle una colección vehículos (que circulan por ella), bastaría cargas solo esos. A su vez cada vehículo podría tener un atributo 'calle', para referenciar al objeto calle en el que se encuentra.
Cuando se cambia de calle (otra distinta), se descarga la previa para cargar la nueva...
Intenta diseñar un objeto calle, edificio y ciudad.

Una colección es una lista de objetos que puede ser tanto homogéneos como heterogéneos, el diseño estbalece lo deseable y al caso, suelen abundar las colecciones cuyo contenido son del mismo tipo "Colección de tipo x"... una colección tiene métodos tales como: añadir (al final), eliminar (del final), insertar (en cierta posición), Borrar (de cierta posición), vaciar (por completo), listar (desde x hasta y), enumerar (todos), Devolver (el enésimo objeto en la colección), y algunos más complejos como 'UnirAOtraColeccion, Clonar, Copiar, etc...
y suele tener atributos del tipo: Vacia, Cantidad, Tipo para señalar si la colección está vacía, cuantos objetos contiene y el tipo de objetos que aloja. Incluso puede hacerse uno como actual y tener un atributo IndiceActual, que puede ser leído y cambiado...
Según la necesidad se crea o no, por ejemplo en una bicicleta, la colección ruedas, no precisa un atributo 'indiceActual', además siendo sólo 2 es fácl acceder a una y saber cual de ellas es (trasera, delantera), pero (por ejemplo) en una ciudad saber el nombre de la calle actual seleccionada, si resulta conveniente... ya que por ejemplo podría ser deseable 'conducir' un vehículo a dicho destino.
Así, un método Conducir (a la calle x)... movería un vehívulo hacia dicha calle, haciéndolo más complejo, debería encontrar el trazado desde su ubicación actual hasta el destino, y al llegar allí detenerse  y avisar...

Piensa en objetos de la vida real y trata de 'visualizarlo' todo desde esa perspectiva de la manipulación, propiedades que tienen y lo que se puede hacer con ello...


En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.709



Ver Perfil
Re: Duda carga de objetos POO
« Respuesta #2 en: 9 Enero 2018, 13:48 »

No sé si es una manera correcta de trabajar, o es mejor cargar los Puestos y según necesite ir cargando y descargando las listas. Si quisiera cargar todos los puestos, tendría en memoría muchísimos datos, y no sé si eso está bien.

Es precisamente por esa necesidad que existe la interfáz IEnumerable<T> (o IEnumerable(Of T) en VB.NET) de evaluación vaga y el tipo Lazy<T> (o Lazy(Of T) en VB.NET) para la inicialización/instanciación vaga de objetos.

La interfáz IEnumerable, o colección enumerable, provee lo que se conoce como un enumerador, que es un mecanismo para obtener el elemento actual en la colección enumerable, mover al siguiente elemento, y reiniciar. El enumerador solamente debe preocuparse por saber como obtener el siguiente elemento en la colección enumerable, por lo que no es necesario que la colección entera esté alojada en memoria ni saber cuantos elementos hay en total; este comportamiento o implementación se traduce en una optimización de varios aspectos, empezando por el más obvio: el consumo de memoria.

Practicamente todas las colecciones disponibles en los espacios de nombre de la librería de .NET Framework implementan la la interfáz IEnumerable, como los tipos List, Dictionary, Array, Stack, Collection y etcétera, pero ojo, eso no quiere decir que todos los tipos de colecciones sean de evaluación vaga, cada tipo tiene una implementación distinta para servir a un propósito específico, así que si quieres asegurarte de beneficiarte de la evaluación vaga entonces usa directamente la interfáz IEnumerable.

El tipo Lazy<T>, por lo general lo usarías en escenarios de programación asincrónica y para prevenir la inicialización de una instancia que sea bastante pesada... hasta que realmente necesites acceder/leer ese objeto.

Te recomiendo unas lecturas importantes para comprender los conceptos básicos:

Citar
Lazy initialization of an object means that its creation is deferred until it is first used. (For this topic, the terms lazy initialization and lazy instantiation are synonymous.) Lazy initialization is primarily used to improve performance, avoid wasteful computation, and reduce program memory requirements.

Citar
By initializing objects in a lazy manner, you can avoid having to create them at all if they are never needed, or you can postpone their initialization until they are first accessed



Bien, ahora que ya he explicado que es cada cosa, te mostraré como puedes reproducir las diferencias a través de varios ejemplos (básicos) basados en el escenario o problema que propones...

Primero de todo, para estos ejemplos crearemos un tipo como éste para representar la información básica de un cliente:

Código
  1. Public NotInheritable Class Customer
  2.  
  3.    Public Property Name As String
  4.    Public Property Surname As String
  5.    Public Property Buffer As Byte()
  6.  
  7.    Public ReadOnly Property InstanceId As Guid
  8.        Get
  9.            If (Me.instanceIdB = Guid.Empty) Then
  10.                Me.instanceIdB = Guid.NewGuid()
  11.            End If
  12.            Return Me.instanceIdB
  13.        End Get
  14.    End Property
  15.    Private instanceIdB As Guid
  16.  
  17.    Private Sub New()
  18.    End Sub
  19.  
  20.    Public Sub New(name As String, surname As String)
  21.        Me.Name = name
  22.        Me.Surname = surname
  23.        Me.Buffer = New Byte(4096) {}
  24.    End Sub
  25.  
  26.    Public Overrides Function ToString() As String
  27.        Return Me.InstanceId.ToString()
  28.    End Function
  29.  
  30. End Class

...es solo un ejemplo cualquiera, mi intención al escribir este ejemplo ha sido que una instancia del tipo Customer ocupe bastantes bytes.



Bien, por lo general, podriamos decidir crear una colección genérica de tipo List<T> (o List(Of T) en VB.NET) para almacenar varias instancias de la clase Customer, e iterar la colección para mostrar cualquier tipo de información de cada Customer, quedando algo parecido a esto:

Código
  1. Imports System
  2. Imports System.Collections.Generic
  3. Imports System.Threading
  4.  
  5. Public Module Module1
  6.  
  7.    Private customers As List(Of Customer)
  8.    Private customerCount As Integer
  9.  
  10.    Private Sub BuildCustomers(ByRef collection As List(Of Customer), ByVal amount As Integer)
  11.        If (collection Is Nothing) Then
  12.            collection = New List(Of Customer)
  13.        ElseIf (collection.Any) Then
  14.            collection.Clear()
  15.        End If
  16.  
  17.        For i As Integer = 0 To (amount - 1)
  18.            collection.Add(New Customer(String.Empty, String.Empty))
  19.        Next i
  20.    End Sub
  21.  
  22.    Public Sub Main()
  23.        ' Construimos la lista de clientes.
  24.        Module1.BuildCustomers(Module1.customers, 100000)
  25.        ' En este punto, la instanciación de todos los objetos en la colección
  26.        ' habrá alcanzado un consumo de memoria sobre los 500 megabytes aprox.
  27.  
  28.        ' Mostramos la cantidad de elementos en la lista
  29.        ' (la propiedad Count debe realizar una iteración completa, así que puede tardar unos segundos).
  30.        Console.WriteLine(String.Format("Customers Count: {0}", Module1.customers.Count))
  31.  
  32.        ' Iteramos cada elemento en la lista.
  33.        For Each c As Customer In Module1.customers
  34.            Console.WriteLine(String.Format("Customer {0}; Unique Id: {1}",
  35.                                            Interlocked.Increment(Module1.customerCount), c.ToString()))
  36.        Next c
  37.  
  38.        ' Ya no necesitamos la lista, así que liberarariamos recursos administrados innecesarios,
  39.        ' y forzamos una recolección del GarbageCollector para un efecto inmediato.
  40.        Module1.customers.Clear()
  41.        Module1.customers = Nothing
  42.        GC.Collect()
  43.        GC.WaitForPendingFinalizers()
  44.        GC.WaitForFullGCApproach()
  45.        GC.WaitForFullGCComplete()
  46.        ' En este punto, la carga de objetos en memoria se reduce al máximo posible,
  47.        ' en mi caso el consumo total es de 80 mb aprox.
  48.  
  49.        Console.WriteLine("Press any key to exit...")
  50.        Console.ReadKey(intercept:=True)
  51.        Environment.Exit(0)
  52.    End Sub
  53.  
  54. End Module

¿Qué ocurre con esto?, pues que todos los elementos de la colección se inicializan, se asigna un espacio en el bloque de memoria para cada elemento de la colección, y evidentemente si tenemos en cuenta el tamaño en bytes de una única instancia de la classe Customer pues... 100.000 instancias simultaneas resultan en un gran consumo de memoria...





Cuando un elemento Customer ha sido inicializado y ya hemos trabajado con él, no necesitamos que siga albergando espacio en memoria, queremos desechar ese consumo adicional que ya no necesitamos para nada, y aquí es donde .NET Framework nos ofrece la solución al problema: IEnumerable<T>.

Este código de aquí abajo es practicamente lo mismo que el anterior con el uso de List<T>, solo que ha sido adaptado para el uso de IEnumerable<T> mediante una función iteradora y así demostrar el beneficio que nos interesa obtener...

Código
  1. Imports System
  2. Imports System.Collections.Generic
  3. Imports System.Threading
  4.  
  5. Public Module Module1
  6.  
  7.    Private customers As IEnumerable(Of Customer)
  8.    Private customerCount As Integer
  9.  
  10.    Private Iterator Function BuildCustomers(ByVal amount As Integer) As IEnumerable(Of Customer)
  11.        For i As Integer = 0 To amount
  12.            Yield New Customer(String.Empty, String.Empty)
  13.        Next i
  14.    End Function
  15.  
  16.    Public Sub Main()
  17.        ' Construimos la colección de clientes.
  18.        Module1.customers = Module1.BuildCustomers(100000)
  19.        ' En este punto, el consumo de memoria es mínimo, alcanzando los 12 mb aprox.
  20.  
  21.        ' Mostramos la cantidad de elementos en la colección
  22.        Console.WriteLine(String.Format("Customers Count: {0}", Module1.customers.Count))
  23.  
  24.        ' Iteramos cada elemento en la colección.
  25.        For Each c As Customer In Module1.customers
  26.            Console.WriteLine(String.Format("Customer {0}; Unique Id: {1}",
  27.                                            Interlocked.Increment(Module1.customerCount), c.ToString()))
  28.        Next c
  29.        ' En este punto, el consumo de memoria es mínimo, sin cambios, puesto que al iterar, los elementos se han evaluado de forma vaga.
  30.  
  31.        Module1.customers = Nothing
  32.        Console.WriteLine("Press any key to exit...")
  33.        Console.ReadKey(intercept:=True)
  34.        Environment.Exit(0)
  35.    End Sub
  36.  
  37. End Module

El beneficio en la optimización del consumo de memoria queda bastante claro:





Te muestro un ejemplo para el uso del tipo Lazy:

Código
  1. Imports System
  2. Imports System.Collections.Generic
  3. Imports System.Threading
  4.  
  5. Public Module Module1
  6.  
  7.    Private lazyCustomers As List(Of Lazy(Of Customer))
  8.    Private customerCount As Integer
  9.  
  10.    Private Function BuildCustomers(ByVal amount As Integer) As List(Of Lazy(Of Customer))
  11.        Dim collection As New List(Of Lazy(Of Customer))
  12.        For i As Integer = 0 To amount
  13.            collection.Add(New Lazy(Of Customer)(
  14.                           Function() As Customer
  15.                               Return New Customer(String.Empty, String.Empty)
  16.                           End Function))
  17.        Next i
  18.        Return collection
  19.    End Function
  20.  
  21.    Public Sub Main()
  22.        ' Construimos la instancia de inicialización vaga con la colección de clientes.
  23.        Module1.lazyCustomers = Module1.BuildCustomers(100000)
  24.        ' En este punto, el consumo de memoria es mínimo, alcanzando los 12 mb aprox,
  25.        ' puesto que todavía NO hemos inicializado ningún elemento de la colección.
  26.  
  27.        Console.WriteLine(String.Format("Lazy Customers Count: {0}", Module1.lazyCustomers.Count))
  28.  
  29.        For Each lz As Lazy(Of Customer) In Module1.lazyCustomers
  30.            Console.WriteLine(String.Format("Customer {0}; Unique Id: {1}",
  31.                                            Interlocked.Increment(Module1.customerCount), lz.Value.ToString()))
  32.        Next lz
  33.        ' Cuando accedemos a la propiedad 'Lazy(Of T).Value' es cuando inicializamos el objecto de inicialización vaga,
  34.        ' así que al terminar la iteración hemos inicializaco todos los elementos, por lo que en este punto el consumo de memoria rondará los 500 megabytes aprox, como en el primer ejemplo.
  35.  
  36.        ' Ya no necesitamos la colección, así que liberarariamos recursos administrados innecesarios,
  37.        ' y forzamos una recolección del GarbageCollector para un efecto inmediato.
  38.        Module1.lazyCustomers.Clear()
  39.        Module1.lazyCustomers = Nothing
  40.        GC.Collect()
  41.        GC.WaitForPendingFinalizers()
  42.        GC.WaitForFullGCApproach()
  43.        GC.WaitForFullGCComplete()
  44.        ' En este punto, la carga de objetos en memoria se reduce al máximo posible,
  45.        ' en mi caso el consumo total es de 20 mb aprox.
  46.  
  47.        Console.WriteLine("Press any key to exit...")
  48.        Console.ReadKey(intercept:=True)
  49.        Environment.Exit(0)
  50.    End Sub
  51.  
  52. End Module



Por supuesto podemos combinar el tipo Lazy<T> e IEnumerable<T>:

Código
  1. Imports System
  2. Imports System.Collections.Generic
  3. Imports System.Threading
  4.  
  5. Public Module Module1
  6.  
  7.    Private lazyCustomers As IEnumerable(Of Lazy(Of Customer))
  8.    Private customerCount As Integer
  9.  
  10.    Private Iterator Function BuildCustomers(ByVal amount As Integer) As IEnumerable(Of Lazy(Of Customer))
  11.        For i As Integer = 0 To amount
  12.            Yield New Lazy(Of Customer)(
  13.                           Function() As Customer
  14.                               Return New Customer(String.Empty, String.Empty)
  15.                           End Function)
  16.        Next i
  17.    End Function
  18.  
  19.    Public Sub Main()
  20.        ' Construimos la instancia de inicialización vaga con la colección de clientes.
  21.        Module1.lazyCustomers = Module1.BuildCustomers(100000)
  22.        ' En este punto, el consumo de memoria es mínimo, alcanzando los 12 mb aprox,
  23.        ' puesto que todavía NO hemos inicializado ningún elemento de la colección.
  24.  
  25.        Console.WriteLine(String.Format("Lazy Customers Count: {0}", Module1.lazyCustomers.Count))
  26.  
  27.        For Each lz As Lazy(Of Customer) In Module1.lazyCustomers
  28.            Console.WriteLine(String.Format("Customer {0}; Unique Id: {1}",
  29.                                            Interlocked.Increment(Module1.customerCount), lz.Value.ToString()))
  30.            ' Cuando accedemos a la propiedad 'Lazy(Of T).Value' es cuando inicializamos el objecto de inicialización vaga.
  31.        Next lz
  32.        ' Al terminar la iteración, en este punto no hay cambios en el consumo de memoria,
  33.        ' puesto que hemos utilizado una colección enumerable.
  34.  
  35.        Module1.lazyCustomers = Nothing
  36.        Console.WriteLine("Press any key to exit...")
  37.        Console.ReadKey(intercept:=True)
  38.        Environment.Exit(0)
  39.    End Sub
  40.  
  41. End Module



IEnumerable y Lazy son dos propuestas para fines distintos, aunque combinables para un mismo fin, y yo solo te he mostado ejemplos básicos de su utilización en escenarios sincrónicos; al final la solución más óptima y adecuada a tu problema siempre dependerá de lo que realmente quieras hacer y como sea realmente necesario hacerlo...

Espero que esto haya servido de ayuda, al menos.

Saludos.
« Última modificación: 9 Enero 2018, 14:28 por Eleкtro » En línea


Devilkeeper

Desconectado Desconectado

Mensajes: 12


Ver Perfil
Re: Duda carga de objetos POO
« Respuesta #3 en: 12 Enero 2018, 19:08 »

Muchísimas gracias a los dos por vuestras respuestas tan elaboradas.

Aunque en mi caso no voy a cargar ni 100 registros, voy a implementar el Lazy Loading para ir aprendiendo su uso. Ya iré contando que tal, he encontrado otros recursos para seguir documentándome. Muchas veces buscas algo que tiene un nombre concreto, pero como no lo conoces, no encuentras nada de informacion.

Un saludo.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[Duda C#] Problema con visivilidad de objetos
.NET (C#, VB.NET, ASP)
~~ 2 2,161 Último mensaje 8 Octubre 2007, 14:01
por ~~
Duda lista de de datos y objetos « 1 2 »
Java
Dem0ny 11 4,554 Último mensaje 13 Marzo 2009, 18:05
por sapito169
duda con objetos en java...
Foro Libre
artis 2 1,098 Último mensaje 2 Mayo 2012, 03:36
por exel
Objetos con VBScript, duda muy básica
Programación Visual Basic
prooving 6 3,163 Último mensaje 14 Junio 2012, 22:43
por prooving
[Duda] Interfaces (objetos).
Java
The Swash 3 1,339 Último mensaje 19 Septiembre 2012, 22:41
por The Swash
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines