• C# ref用法,实现引用传递(地址传递)


    前言:

    今天这篇文章我们简单学习一下C# ref的用法,在看别人的代码不至于看不懂逻辑,虽然这是一个比较简单的知识点,但是还是值得我们去学习一下关于这个知识点一些概念,我们知道在C# 中我们的函数参数,一般都为值引用,C#是一门解释型语言,其中对指针进行了封装,因此用户无法直接调用对象的指针,无法调用对象的指针,就不能地址引用了吗?显然我们是有其他的方法,ref在C#中起到地址引用的作用,使用ref就可以对对象进行地址引用了。创作不易,点赞关注评论收藏,你的点赞是我创作的动力,也是我学习的方向。
    d97acf8bd6adc01a9bf0ed9bab50b0c2.gif

    ref概述

    关键字 ref 指示变量是引用或另一个对象的别名。 它在五个不同的上下文中使用:

    1. 在方法签名和方法调用中,按引用将参数传递给方法。 有关详细信息,请参阅按引用传递参数。
    2. 在方法签名中,按引用将值返回给调用方。 有关详细信息,请参阅引用返回值。
    3. 在成员正文中,指示引用返回值是否作为调用方欲修改的引用被存储在本地。 或指示局部变量按引用访问另一个值。 有关详细信息,请参阅 Ref 局部变量。
    4. 在struct 声明中,声明 ref struct 或 readonly ref struct。 有关详细信息,请参阅ref struct 一文。
    5. ref struct在声明中,声明字段是引用。 ref请参阅字段文章。

    按引用传递参数

    在方法的参数列表中使用 ref 关键字时,它指示参数按引用传递,而非按值传递。 ref 关键字让形参成为实参的别名,这必须是变量。 换而言之,对形参执行的任何操作都是对实参执行的。

    1.未使用ref进行值传递

    如图我们调用函数没有使用ref这里只是传递值,并没传递引用,用C语言的概念我们没有传递地址,所以它的初始的值不会随着函数改变而改变。
    image.png

    2.使用ref进行引用传递

    如图我们使用了ref的方法,注意ref的使用和我们之前的一些语法有一点区别,其实我们可以把ref看作C语言的*指针标记,我们使用ref调用函数时,传递的就是地址,所以会跟着函数改变我们的初始值,因为我们在函数改变值了,实现引用传递
    image.png

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace Test10113
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

        private void Form1_Load(object sender, EventArgs e)
        {
            int test = 100;
            Console.WriteLine(test);
            data(ref test);
            Console.WriteLine(test);
        }
        public  void data(ref int test)
        {
            int a = 4000;
            test = a;
            Console.WriteLine(a);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    }

    引用返回值

    引用返回值(或 ref 返回值)是由方法按引用向调用方返回的值。 即是说,调用方可以修改方法所返回的值,此更改反映在所调用方法中的对象的状态中。(讲人话就是:我们平时函数的返回值 return 返回的是一个值,现在用ref返回的就是一个引用传递,就是一个地址传递,这样避免了值类型在方法返回时的浅拷贝操作,提高了效率)

    image.png

     private void Form1_Load(object sender, EventArgs e)
            {
                int test = 100;
               //  Console.WriteLine(test);
                // data(ref test);
                int[] datas = new int[] { 1, 2, 3, 4, 5 ,6,7,8,9,10};
    
                int data1 =  Find(datas);
                Console.WriteLine(data1);
    
                ref int data =ref Find(datas);
                 datas[5] = 100;
               // Console.WriteLine(test);
                for(int i = 0; i < datas.Length; i++)
                {
                    Console.WriteLine(datas[i]);
                }
                Console.WriteLine(data);
            }
            public  int data(int test)
            {
                int a = 4000;
                Console.WriteLine(a);
                return  test;
            }
            public static ref int Find(int[] data)
            {
                return ref data[5];
            }
    
    • 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

    ref 局部变量

    ref 局部变量用于指代使用 return ref 返回的值。 无法将 ref 局部变量初始化为非 ref 返回值。 也就是说,初始化的右侧必须为引用。 任何对 ref 本地变量值的修改都将反映在对象的状态中,该对象的方法按引用返回值。
    可在以下两个位置使用 ref 关键字来定义 ref 局部变量:(通俗点讲就是我们局部变量赋值也是值,使用ref之后就是一个引用传递,就是个地址,某个值改变它也会跟着改变

    • 在变量声明之前。
    • 紧接在调用按引用返回值的方法之前。

    image.png

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace Test10113
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
    
            private void Form1_Load(object sender, EventArgs e)
            {
                int test = 100;
                //  Console.WriteLine(test);
                // data(ref test);
                int[] datas = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
                ref int a = ref datas[0];
                datas[0] = 100;
                Console.WriteLine(a);
                int b = a + 10;
                Console.WriteLine(b);
              /*  int data1 = Find(datas);
                Console.WriteLine(data1);
    
                ref int data = ref Find(datas);
                datas[5] = 100;
                // Console.WriteLine(test);
                for (int i = 0; i < datas.Length; i++)
                {
                    Console.WriteLine(datas[i]);
                }
                Console.WriteLine(data);*/
            }
            public int data(int test)
            {
                int a = 4000;
                Console.WriteLine(a);
                return test;
            }
            public static ref int Find(int[] data)
            {
                return ref data[5];
            }
        }
    }
    
    
    • 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

    总结

    这篇文章比较简单,只是简单的学习一下,对它有更多的认识,在有需求的时候最起码有路子,虽然很简单,但是也是可以学到东西的,我们学习了新的知识,对我们的知识储备及技术又有新的一点点的进步,C#的技术就是先简单再难嘛,积少成多之后才会成长才会进步,我们要不断的学习不断的探索,才能有学习的动力,才会有学习的欲望,创作不易,点赞评论收藏关注,嘿嘿,不喜勿喷!!!!

    image.png

  • 相关阅读:
    Delta Lake: High-Performance ACID Table Storage over Cloud Object Stores
    CSS基础入门
    MySQL数据库的MVCC详解
    有关于torch.autograd.grad
    计算机基础-BAT入门进阶
    JS10day(api 阶段性完结,正则表达式简介,过滤敏感词案例,注册模块验证案例)
    Kafka生产者(二)
    2023年软考什么时候报名,报名有什么条件?
    如何做好电子内窥镜的网络安全管理?
    多个路径下python库导入
  • 原文地址:https://blog.csdn.net/qq_46104786/article/details/134009783