So if I am iterating using a foreach loop and I have a function inside that takes an argument of the object iterated from list, and lets say i set its value to be different. Why don't I have to use out or ref ? I thought it was only passed by value if it you didn't use out or ref.... I know that a ref you must have initialized the variable before and out you just have to have set its value before return from the method.
It seems like if you a iterating thru a list and pass an object in its actually passed by reference. Consider the following example.
Example
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
{
开发者_如何学JAVApublic string Bar { get; set; }
}
Output:
SetFoo Pre: 1 SetFoo Inside: 1 ::
WithoutRef SetFoo Post: 1 WithoutRef SetFoo Pre: 1 :: WithoutRef SetFoo Inside: 1 :: WithoutRef :: WithRef SetFoo Post: 1 WithoutRef :: WithRefSetFoo Pre: 2 SetFoo Inside: 2 ::
WithoutRef SetFoo Post: 2 WithoutRef SetFoo Pre: 2 :: WithoutRef SetFoo Inside: 2 :: WithoutRef :: WithRef SetFoo Post: 2 WithoutRef :: WithRefSetI Pre: 0 SetI Inside: 2 SetIPost: 0
SetRefI Pre: 0 SetRefI Inside: 3
SetRefI Post: 3
I understand the ref with the integer example but not the above Foo object iteration example.
Thanks!
The reference is passed by value. So the method can still change the contents of the object, it just can't change which object your variable refers to.
See my article on parameter passing for a lot more information, along with my article about reference types and value types.
精彩评论