Pregunta

Entonces, si estoy iterando usando un bucle foreach y tengo una función dentro que toma un argumento del objeto iterado de la lista, y digamos que configuro su valor para que sea diferente. ¿Por qué no tengo que usar o ref? Pensé que solo se pasaba por valor si no se usaba o no se ref ... Sé que un ref debe haber inicializado la variable antes y solo debe haber establecido su valor antes de regresar del método.

Parece que si iteras a través de una lista y pasas un objeto en su realidad, se pasa por referencia. Considere el siguiente ejemplo.

Ejemplo

class Program
    {
        static void Main(string[] args)
        {

            List<Foo> list = new List<Foo>();
            list.Add(new Foo() { Bar = "1" });
            list.Add(new Foo() { Bar = "2" });



            foreach (var f in list)
            {
                Foo f2 = f; 
                Console.WriteLine("SetFoo Pre: " + f2.Bar);
                SetFoo(f2);
                Console.WriteLine("SetFoo Post: " + f2.Bar);

                Console.WriteLine("SetFooRef Pre: " + f2.Bar);
                SetFooRef(ref f2);
                Console.WriteLine("SetFooRef Post: " + f2.Bar);
                Console.WriteLine("");
            }




            Console.WriteLine("");

            int i = 0;
            // Not using ref keyword
            Console.WriteLine("SetI Pre: " + i);
            SetI(i);
            Console.WriteLine("SetI Post: " + i);

            // Using ref keyword
            Console.WriteLine("SetRefI Pre: " + i);
            SetRefI(ref i);
            Console.WriteLine("SetRefI Post: " + i);
        }


        private static void SetRefI(ref int i)
        {
            i = 3;
            Console.WriteLine("SetRefI Inside: " + i);
        }

        private static void SetI(int i)
        {
            i = 2;
            Console.WriteLine("SetI Inside: " + i);
        }

        private static void SetFooRef(ref Foo f)
        {
            f.Bar = String.Format("{0} :: {1}", f.Bar, "WithRef");
            Console.WriteLine("SetFooRef Inside: " + f.Bar);
        }

        private static void SetFoo(Foo f)
        {
            f.Bar = String.Format("{0} :: {1}", f.Bar, "WithoutRef");
            Console.WriteLine("SetFoo Inside: " + f.Bar);
        }
    }


    class Foo
    {
        public string Bar { get; set; }
    }

Salida:

  

SetFoo Pre: 1 SetFoo Inside: 1 ::
  SinRef SetFoo Publicar: 1 SinRef
  SetFoo Pre: 1 :: SinRef SetFoo
  Interior: 1 :: Sin referencia :: Con referencia
  Publicación de SetFoo: 1 sin referencia :: con referencia

     

SetFoo Pre: 2 SetFoo Inside: 2 ::
  SinRef SetFoo Publicar: 2 SinRef
  SetFoo Pre: 2 :: SinRef SetFoo
  Interior: 2 :: Sin referencia :: Con referencia
  SetFoo Post: 2 sin referencia :: con referencia

     

SetI Pre: 0 SetI Inside: 2 SetIPost: 0

     

SetRefI Pre: 0 SetRefI Inside: 3
  Publicación SetRefI: 3

Entiendo la referencia con el ejemplo entero pero no con el ejemplo de iteración de objeto Foo anterior.

¡Gracias!

¿Fue útil?

Solución

La referencia se pasa por valor. Por lo tanto, el método aún puede cambiar el contenido del objeto, simplemente no puede cambiar a qué objeto se refiere su variable.

Consulte mi artículo sobre el paso de parámetros para obtener más información, junto con mi artículo sobre tipos de referencia y tipos de valor .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top