none
Como pasar valor de objeto RRS feed

  • Pregunta

  • Hola ,no llevo mucho en programación y me encontré con un problema  al querer pasar un objeto Memoria a una Lista de Memoria que cree ,cuando modifico M se me modifican todos los objetos de esa matriz ,como puedo solucionarlo ?. Adjunto código.

    public  class ProcesosMemoria
        {
            
            public List<Memoria> memorias=new List<Memoria>();
            public bool encuentra=false;
            public Memoria Mem = new Memoria();
            public Memoria Mem2 = new Memoria();
            public string[] k;
            public string[] z;
            int n;
    
            int cont = 88;
    
           
    
            private void FIRST(List<Proceso> CPU)   
            {
                     
                encuentra = false;
    
                if (CPU.Count>0)
                {
                    int z = 0;
                    while( z <CPU.Count)
                    {
                     int n = 0;
                      while  (   (n < Mem.Particiones.Count ) & (encuentra==false) )
                      {
                            if ((Mem.Particiones[n].tamaño - CPU[z].Tamaño) >= 0  &  Mem.Particiones[n].habilitada==true)
                            {
                                encuentra = true; Mem.Particiones[n].nombre = CPU[z].Nombre;Mem.tiempo = cont;
                               Mem.Particiones[n].habilitada = false;
                               Mem.Particiones[n].tamaño = CPU[z].Tamaño;
                            }
    
                        n++;
                      }
                        if (encuentra==false) { Mem.ProcesosEnCola.Add(CPU[z].Nombre); }
    
                        encuentra = false ;
                        z++;
                    }
    
                   
                    memorias.Add(Mem) ;
                    
                }   
            }
    }
    
     public class Memoria
        {
            
            public int tiempo;
            public List<string> ProcesosEnCola = new List<string>();       
            public string tipo;
            public List<Particion> Particiones = new List<Particion>();
            public List<Particion> ParticionesCopia = new List<Particion>();
            public int TotalTamaño;
            public int TotalTemporal;
     
        }

    viernes, 22 de febrero de 2019 11:13

Respuestas

  • El principio es el mismo que con la Memoria, es decir, tienes que hacer un "new" cada vez que quieras una copia nueva y no quieras que las modificaciones de esa copia afecten a las otras copias.

    En otras palabras, hazte a la idea de que cuando tienes un tipo-referencia y haces esto:

    a=b;

    eso NO copia b en a. Sigue habiendo una única copia de los datos, y tanto b como a acceden a ese mismo dato único.

    En cambio si haces

    a = new Tipo(); a.propiedad = b.propiedad;

    entonces sí que a y b tienen dos copias de la propiedad... a no ser que "propiedad" a su vez sea también un tipo-referencia en cuyo caso te vuelve a suceder lo mismo y tienes que hacerle también un "new".

    • Marcado como respuesta LesPro1221 sábado, 23 de febrero de 2019 13:20
    sábado, 23 de febrero de 2019 8:49
    Moderador

Todas las respuestas

  • cuando modifico M se me modifican todos los objetos de esa matriz ,como puedo solucionarlo

    Ah, acabas de caer en la trampa de los objetos tipo-referenca en contraste con los objetos tipo-valor.

    Cuando pasas a un metodo un objeto tipo-valor ("value-type"), el objeto se copia. Pero cuando pasas un tipo-referencia ("reference-type") lo que se copia es la referencia que es una especie de "puntero" que apunta al Heap, el cual almacena el contenido del objeto. Si copias la referencia, la referencia copiada sigue apuntando al mismo contenido original al que apuntaba la primera referencia, y por lo tanto si cambias el contenido, se ve cambiado en todas las referencias que apuntaban a él. Esto es lo que te está pasando.

    Primera solución (no recomendada en este caso): Usa objetos tipo-valor. Se construyen usando un struct en lugar de un class.

    Segunda solución: Haz un "new" del objeto para crear una nueva instancia (que implica una nueva referencia) a cada iteración de tu bucle.

    Es decir, en lugar de declarar public Memoria Mem = new Memoria(); al principio de tu clase, declara Memoria Mem = new Memoria(); dentro del bucle.

    viernes, 22 de febrero de 2019 11:37
    Moderador
  • hola

    cuando estas iterando debes definir el objeto lo mas local posible y no de forma global

    ya que recuerda los objeto se acceden por referencia con un puntero, con lo cual modifican la misma direccion en memoria

    public class ProcesosMemoria { private List<Memoria> memorias = null; int cont = 88; public ProcesosMemoria() { memorias=new List<Memoria>(); }

    public List<Memoria> Memorias {

    get { return this.memorias; }

    }

    private void FIRST(List<Proceso> CPU) { Memoria Mem = new Memoria(); bool encuentra = false; if (CPU.Count > 0) return; int z = 0; while( z < CPU.Count) { int n = 0; while ( (n < Mem.Particiones.Count ) & (encuentra==false) ) { if ((Mem.Particiones[n].tamaño - CPU[z].Tamaño) >= 0 & Mem.Particiones[n].habilitada==true) { encuentra = true; Mem.Particiones[n].nombre = CPU[z].Nombre;Mem.tiempo = cont; Mem.Particiones[n].habilitada = false; Mem.Particiones[n].tamaño = CPU[z].Tamaño; } n++; } if (encuentra==false) { Mem.ProcesosEnCola.Add(CPU[z].Nombre); } encuentra = false ; z++; } memorias.Add(Mem) ; } }


    trata de no definir tanto de forma global, el ambito de uso de la variable es importante

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina


    viernes, 22 de febrero de 2019 13:41
  • Hola,Gracias eso soluciono algunas cosas ya no repite los campos excepto un problema con uno de los campos dentro del objeto memoria que es una lista de particiones .Anteriormente había declarado en la clase Procesos memoria un objeto lista de particiones .

    public class ProcesosMemoria { public List<Particion> Part = new List<Particion>(); public List<Memoria> memorias = new List<Memoria>();

    Yo necesito trabajar todo el tiempo(no puedo hacer como con la memoria y crear uno nuevo,porque necesito los datos o al menos no se me ocurre manera) con los valores de esa lista Part modificarlos ,colocarlos en la nueva memoria creada e insertar esa memoria en la lista de memorias ,lo que pasa es que modifica todos las particiones de toda memoria en la lista memorias,y no estoy encontrando la manera de hacerlo funcionar,desde ya gracias por tu aporte .


    sábado, 23 de febrero de 2019 2:04
  • El principio es el mismo que con la Memoria, es decir, tienes que hacer un "new" cada vez que quieras una copia nueva y no quieras que las modificaciones de esa copia afecten a las otras copias.

    En otras palabras, hazte a la idea de que cuando tienes un tipo-referencia y haces esto:

    a=b;

    eso NO copia b en a. Sigue habiendo una única copia de los datos, y tanto b como a acceden a ese mismo dato único.

    En cambio si haces

    a = new Tipo(); a.propiedad = b.propiedad;

    entonces sí que a y b tienen dos copias de la propiedad... a no ser que "propiedad" a su vez sea también un tipo-referencia en cuyo caso te vuelve a suceder lo mismo y tienes que hacerle también un "new".

    • Marcado como respuesta LesPro1221 sábado, 23 de febrero de 2019 13:20
    sábado, 23 de febrero de 2019 8:49
    Moderador
  • Gracias, me sirvió.
    sábado, 23 de febrero de 2019 13:21