zoukankan      html  css  js  c++  java
  • C#程序员请不要混淆引用类型和ref引用传参

    先看一段代码1:

            static void Main(string[] args)
            {           
                StringBuilder sb = new StringBuilder("1");
                test(sb);
                Console.WriteLine(sb.ToString());
                Console.Read();
            }

            static void test(StringBuilder sb)
            {
                sb = new StringBuilder("2");
            }

    错误的观念:

     程序输出"2",因为StringBuilder是引用类型,函数内部sb变量重新指向了托管堆中的新对象,函数返回后,外部的sb变量也指向了这个新对象,因为是引用类型吗,我传的是引用。

     在错误的观念中,认为 “ref引用传参” 仅对.net中的另一种基本类型——值类型有用。

      这种错误观念通常源于这样的经验,看代码2:

            static void Main(string[] args)
            {           
                StringBuilder sb = new StringBuilder("1");
                test(sb);
                Console.WriteLine(sb.ToString());
                Console.Read();
            }

            static void test(StringBuilder sb)
            {
                sb.Append("2");
            }

     我们通常会很自豪的说:“看吧,程序输出12,这就是引用类型的特点,如果换成值类型就不是了!”。我们得出的结论并没有错,实际上,这正是引用类型的特点!然而将这个观念扩大到代码1的情况,就错了!

     正确的理解:

    程序正确的输出是“1”,并没有因为StringBuilder是引用类型,就应该输出“2” 。如果要输出“2”,需要加ref:

            static void Main(string[] args)
            {           
                StringBuilder sb = new StringBuilder("1");
                test(ref sb);
                Console.WriteLine(sb.ToString());
                Console.Read();
            }

            static void test(ref StringBuilder sb)
            {
                sb = new StringBuilder("2");
            }

    对于ref传参,只要记住一点:对于值类型来说传的是值的地址,对于引用类型来说传的是地址的地址。

    对于引用类型,同样记住一点:引用类型本身的地址是一个值类型。就像我们学习c时,指针本身的地址就是一个int。

    好吧,用c来理解c#果然有点拗!直观的理解:引用类型对象本身不改变,只改变对象的属性时,我们在操作同一个对象;

    如果连对象本身都可能会改变,又要保证在操作同一个对象,就用ref传引用类型的对象吧!

    为什么不用string作测试呢?

    因为string对象虽然是引用类型,但不能改变对象的属性CharArray,每次返回的都是新对象(看起来像值类型,其实不是!)。

            static void Main(string[] args)
            {           
                String s = "1"
                test(s);
                Console.WriteLine(s);
                Console.Read();
            }

            static void test(String s)
            {
                s="2";
            }

    程序输出"1",加 ref后输出"2"。然而我没法写出代码2了,看来string这个不可变引用类型并不适合作本文的测试,千万不要认为string是什么混血儿。

  • 相关阅读:
    jQuery的选择器中的通配符[id^='code']
    chorme插件 ,在浏览器上模拟手机,pad 查看网页|前端技术开发必备插件
    http://hsax.kcpci.com:81/admin/login.aspx
    ashx页面返回json字符串|jQuery 的ajax处理请求的纠结问题
    用NPOI创建Excel、合并单元格、设置单元格样式、边框的方法
    DataTable 导入到Excel的最佳选择Npoi
    隐藏和显示服务器端控件以及Html控件
    JS只能输入数字,数字和字母等的正则表达式
    把本地表导入远程表
    [flex & bison]编译器杂谈
  • 原文地址:https://www.cnblogs.com/slmk/p/2406429.html
Copyright © 2011-2022 走看看