C# 值類型作為函數形參,形參被修改,不影響原值。
這是我們在初始學習編程時需要記住的內容,我們也是一直這樣踐行的。
先說結論:這是不准確的。
為什么提出這樣看似很淺顯的問題,是因為有次我在使用ArraySegment<byte>
值類型時,有感而發。
這是一個托管的值類型,表示array的一個片斷, 在用做websocket接收數據的載體時我發現每次值傳遞后, 這個ArraySegment<byte>
貌似發生了變化。
這勾起了我的探究欲。
我們做一個簡單的實驗, 來證明【值類型作為函數形參,形參被修改,不影響原值】不准確。
struct Slice
{
public Array Array { get; set; }
public int Offset { get; set; }
public int Count { get; set; }
}
class Program
{
static void Main(string[] args)
{
var slice = new Slice { Array = Array.CreateInstance(typeof(int), 5)};
Test(slice);
foreach(var i in slice.Array)
{
Console.WriteLine(i);
}
Console.ReadLine();
}
static void Test(Slice tmp)
{
tmp.Array.SetValue(1,1);
tmp.Offset = 1;
tmp.Count = 1;
}
}
// 輸出 0 1 0 0 0
這個簡單的Demo告訴我們:
大部分情況下:“值類型作為函數形參,形參被修改,不影響原值”, 但是如果修改的是值類型的引用類型字段, 原值類型照樣能體現修改。
歸根到底由值類型和引用類型的特性決定:
值類型的變量直接存儲數據,而引用類型的變量持有的是數據的引用,數據存儲在數據堆中;
寬泛地講:函數傳參,都是值傳遞, 只是引用類型傳遞的是 原對象的引用地址值。
本篇文章沒啥干貨,算是日常小記吧,各大佬輕噴。