Ver Mensaje Individual
  #2  
Antiguo 17-01-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Reputación: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Cita:
Se puede pasar un objeto por valor de alguna forma?
Suponiendo que te refieras a que un determinado método cuente con un parámetro con el que pueda recibir un objeto, por defecto, en C#, el objeto se pasará por valor, tal como precisas. Para pasar un parámetro por referencia has de especificarlo, tanto en la cabecera del método como en la llamada al mismo, con la palabra clave "ref".

Lo que acaso esté ocurriéndote es que notes que pasas un objeto como parámetro de un método, varías alguna de sus propiedades en dicho método y, a continuación y fuera ya del método, ves que los valores de las propiedades que cambiaste en el método se mantienen, ¿me equivoco? Pero es que lo que pasas como parámetro cuando se trata de un tipo de objeto será siempre una referencia a dicho objeto, eso es lo que tienes en la variable que pasas como parámetro: una referencia a un objeto.

Es decir, si haces algo así:

Código:
    // Un objeto de ejemplo
    public class UnObjeto : Object
    {
      public string mCadena = string.Empty;
    }

    /* Un evento que aprovechamos para crear
       un objeto, darle un valor a su única
       variable y pasar dicho objeto como
       parámetro en la llamada a un método.
    */
    private void button1_Click(object sender, EventArgs e)
    {
      UnObjeto objeto = new UnObjeto();
      objeto.mCadena = "Un valor para mCadena";

      // En el siguiente mensaje se mostrará el mismo valor
      // tanto como resultado de "UnMetodo(objeto)" como en
      // "objeto.mCadena".

      MessageBox.Show(string.Format("{0} - {1}", 
        UnMetodo(objeto), objeto.mCadena));
    }

    /* Este método recibe el objeto por valor,
       pero, lo que recibe es una variable con
       la referencia a un objeto, con lo que si
       cambiamos el valor de la única variable
       de este objeto de ejemplo este valor se
       mantendrá aún fuera de este método, como
       puede comprobarse más arriba.
    */
    public string UnMetodo(UnObjeto objeto)
    {
      objeto.mCadena = "Nuevo valor de mCadena?";
      return objeto.mCadena;
    }
Pero, parece ser que los parámetros en C# siempre se pasan por valor. Esto se puede comprobar en el siguiente código:

Código:
    public class UnObjeto : Object
    {
      public string mCadena = string.Empty;
    }

    private void button1_Click(object sender, EventArgs e)
    {
      UnObjeto objeto = new UnObjeto();
      objeto.mCadena = "Un valor para mCadena";

      /* En este caso pasamos el valor (como por defecto se
         lleva a cabo siempre en C#) al método "UnMetodo" de
         la variable "mCadena" de "objeto".
         
         Quiere decirse que ahora sí podrá notarse cómo el
         cambio que se hace en dicha variable en el método
         "UnMetodo" no tiene efecto ninguno fuera del método.
         
         El siguiente mensaje mostrará en "{0}" "Nuevo valor
         de mCadena?", mientras que en "{1}" se mostrará tal
         como se espera "Un valor para mCadena", porque la
         propia variable "mCadena" no ha sido afectada en
         "UnMetodo".         
      */
      MessageBox.Show(string.Format("{0} - {1}", 
        UnMetodo(objeto.mCadena), objeto.mCadena));
    }

    public string UnMetodo(string cadena)
    {
      cadena = "Nuevo valor de mCadena?";
      return cadena;
    }
Si fuera menester pasar parámetros por referencia, como queda dicho, hay que anteponer la palabra "clave" "ref" tanto en la cabecera del método en cuestión como en la llamada al mismo, de este modo:

Código:
    public class UnObjeto : Object
    {
      public string mCadena = string.Empty;
    }

    private void button1_Click(object sender, EventArgs e)
    {
      UnObjeto objeto = new UnObjeto();
      objeto.mCadena = "Un valor para mCadena";

      /* 
        Ahora tanto en "{0}" como en "{1}" se mostrará el valor
        modificado de la variable "mCadena", puesto que aunque se
        modifique en el método "UnMetodo" a este se le pasa la
        variable "mCadena" por referencia y no por valor.
      */
      MessageBox.Show(string.Format("{0} - {1}", 
        UnMetodo(ref objeto.mCadena), objeto.mCadena));
    }

    public string UnMetodo(ref string cadena)
    {
      cadena = "Nuevo valor de mCadena?";
      return cadena;
    }
Lamento si te he liado más que otra cosa y el rollo este que acabo de soltar cuando el tema podría haberse resumido tal vez bastante. Si te queda alguna duda coméntala que aquí habrá quien sepa dar cabo a la misma.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita