关于c#:通过ref和out传递

Passing By ref and out

所以,如果我使用foreach循环进行迭代,并且在其中有一个函数,它接受从列表中迭代的对象的参数,假设我将其值设置为不同的值。为什么我不使用out或ref?我以为只有当你不使用out或ref时,它才是按值传递的。我知道一个引用在从方法返回之前,您必须先初始化变量,然后再设置它的值。

看起来像是通过一个列表进行迭代,并在实际通过引用传递的对象中传递一个对象。考虑下面的例子。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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; }
    }

输出:

SetFoo Pre: 1 SetFoo Inside: 1 ::
WithoutRef SetFoo Post: 1 WithoutRef
SetFoo Pre: 1 :: WithoutRef SetFoo
Inside: 1 :: WithoutRef :: WithRef
SetFoo Post: 1 WithoutRef :: WithRef

SetFoo Pre: 2 SetFoo Inside: 2 ::
WithoutRef SetFoo Post: 2 WithoutRef
SetFoo Pre: 2 :: WithoutRef SetFoo
Inside: 2 :: WithoutRef :: WithRef
SetFoo Post: 2 WithoutRef :: WithRef

SetI Pre: 0 SetI Inside: 2 SetIPost: 0

SetRefI Pre: 0 SetRefI Inside: 3
SetRefI Post: 3

我用整数示例了解引用,但不理解上面的foo对象迭代示例。

谢谢!


引用是按值传递的。所以这个方法仍然可以改变对象的内容,它只是不能改变变量引用的对象。

有关参数传递的更多信息,请参阅我的文章,以及关于引用类型和值类型的文章。