Pasando por ref y fuera
-
10-07-2019 - |
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 referenciaSetFoo 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 referenciaSetI 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!
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 .