C# 如果class本身当参数传递是 call by reference , 那前面加上ref有何用呢?

作为IT邦的第一篇文章

就来开这个主题好了

public class ValueModel{    public int Value { get; set; }}public static void Assign(ValueModel model){    model.Value = 10;}public static void Assign(int value){    value = 10;}static void Main(string[] args){    var model = new ValueModel();    Assign(model);    Console.WriteLine($"ValueModel.Value is {model.Value}");//ValueModel.Value is 10        int value = 0;    Assign(value);    Console.WriteLine($"Value is {value}");//Value is 0}

有点基本功的都能够知道如果是用class传入function,在function内修改的话,呼叫端的class也会一併修改

而 ValueType的 int则不会

所以如果希望int也有像reference的效果,加个ref就可以 如下

public static void Assign(ref int value){    value = 10;}static void Main(string[] args){    int value = 0;    Assign(ref value);    Console.WriteLine($"Value is {value}");//Value is 10}

那今天的问题来了 如果ref用在ReferenceType上会怎样?

public static void Assign(ref ValueModel model){    model.Value = 20;}static void Main(string[] args){    {        var model = new ValueModel();        Assign(model);        Console.WriteLine($"ValueModel.Value is {model.Value}");//ValueModel.Value is 10    }    {        var model = new ValueModel();        Assign(ref model);        Console.WriteLine($"ValueModel.Value is {model.Value}");//ValueModel.Value is 20    }}

恩 看起来好像效果一样? 似乎没差别

在这个例子裏面是这样没错,因为我们没有动到关键点 我们修改一下Assign的内容

public static void Assign(ValueModel model){    model = new ValueModel();    model.Value = 10;}public static void Assign(ref ValueModel model){    model = new ValueModel();    model.Value = 20;}static void Main(string[] args){    {        var model = new ValueModel();        Assign(model);        Console.WriteLine($"ValueModel.Value is {model.Value}");//ValueModel.Value is 0    }    {        var model = new ValueModel();        Assign(ref model);        Console.WriteLine($"ValueModel.Value is {model.Value}");//ValueModel.Value is 20    }}

这样应该可以很容易地看出差异了

想像一下

若是没有加上ref的时候 其实方法呼叫时会将传入的物件贴上一个标籤

修改资料是对这个标籤上的物件做修改 而model = new ValueModel(); 其实则是将标籤贴到new出来的物件上

所以去修改的时候 是修改新new出来的物件 而不是呼叫端传入的

那加上ref呢?

他是将外面呼叫端的标籤传入 所以model = new ValueModel();是将外面的标籤给贴到里面new出来的物件上

一开始呼叫端new的物件早就消失不见了
(没有任何方法可以存取他 因为它唯一的标籤已经被撕掉 然后贴到方法内的物件上了)

我们可以再做个实验

static void Main(string[] args){    {        var model = new ValueModel();        var oldmodel = model;        Assign(ref model);        Console.WriteLine($"ValueModel.Value is {model.Value}");//ValueModel.Value is 20        Console.WriteLine($"oldmodel.Value is {oldmodel.Value}");//oldmodel.Value is 0    }}

在呼叫端的model被撕掉标籤以前 我先给它贴上一个oldModel的标籤

就可以清楚看见oldmodel其实根本没有被修改值

其实也可以用GetHashCode来检验是否为同一物件

好了~ 今天分享就此结束!

本人并非本科系出身,也没有受过什么专业训练

都是自己在写Code过程中的感触体会

如果一些专业术语使用不当或是观念不正确,还请海涵指教


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章