C#值类型和引用类型的区别

dotNET全栈开发

共 2875字,需浏览 6分钟

 ·

2021-09-03 19:21

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();
        }
// 值类型传参,值传给tmp变量
        static void Test(Slice tmp)
        {
            tmp.Array.SetValue(1,1);
            tmp.Offset = 1;
            tmp.Count = 1;
        }
    }
    
 // 输出  0 1 0 0 0
slice变量的引用类型属性体现了变化,值类型Offset Count属性不会变化。

这个简单的Demo告诉我们:

大部分情况下:“值类型作为函数形参,形参被修改,不影响原值”, 但是如果修改的是值类型的引用类型字段,原值类型照样能体现修改

归根到底由值类型和引用类型的特性决定:

值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中;

宽泛地讲:函数传参,都是值传递(拷贝), 只是引用类型传递的是原对象的引用或地址值。

本篇文章没啥干货,算是日常小记吧,各大佬轻喷。

基础不牢 地动山摇








回复 【关闭】广
回复 【实战】获取20套实战源码
回复 【被删】
回复 【访客】访
回复 【小程序】学获取15套【入门+实战+赚钱】小程序源码
回复 【python】学微获取全套0基础Python知识手册
回复 【2019】获取2019 .NET 开发者峰会资料PPT
回复 【加群】加入dotnet微信交流群


浏览 31
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报