作为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过程中的感触体会
如果一些专业术语使用不当或是观念不正确,还请海涵指教
在先前的章节里,我们可以常看见 HEAD 这个名词,它指的是什麽呢? // git 恢复文件到初始状...
本篇大纲:tooltips 基础设定、tooltips 进阶应用 今天我们要来讲解算是D3最轻松简...
今天要来说昨天 --save-dev的部分。 昨天文章指路-->https://ithelp....
各位前辈们好,我想询问这题怎麽解~ 我查了很多资料还是不知道怎麽解 谢谢各位前辈 一部路由器有A、B...
SearchMyFiles 今天来认识这个看名字判断应该是找自己的档案的工具? 可是这功能不是从 w...