通过 ref 传递并输出

发布于 2024-08-09 12:33:54 字数 2641 浏览 7 评论 0原文

因此,如果我使用 foreach 循环进行迭代,并且内部有一个函数,该函数接受从列表迭代的对象的参数,并且可以说我将其值设置为不同。 为什么我不必使用 out 或 ref ?我认为只有在您没有使用 out 或 ref 的情况下它才按值传递。...我知道您必须在 ref 之前初始化变量,而 out 您只需在从方法返回之前设置其值即可。

看起来如果您迭代一个列表并在其实际通过引用传递的对象中传递一个对象。考虑以下示例。

示例

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 前:1 SetFoo 内:1 ::
WithoutRef SetFoo 帖子: 1 WithoutRef
SetFoo 上一篇:1 :: WithoutRef SetFoo
内部:1 :: WithoutRef :: WithRef
SetFoo 帖子:1 WithoutRef :: WithRef

SetFoo 前:2 SetFoo 内:2 ::
WithoutRef SetFoo 帖子:2 WithoutRef
SetFoo 上一篇:2 :: WithoutRef SetFoo
内部:2 :: WithoutRef :: WithRef
SetFoo 帖子:2 WithoutRef :: WithRef

SetI 前:0 SetI 内:2 SetIPost:0

SetRefI 前:0 SetRefI 内:3
SetRefI 帖子:3

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

谢谢!

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
    {
        public 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 :: 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

I understand the ref with the integer example but not the above Foo object iteration example.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

表情可笑 2024-08-16 12:33:54

引用是按值传递的。因此该方法仍然可以更改对象的内容,只是无法更改变量引用的对象。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文