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是什么混血儿。

  • 相关阅读:
    WSP部署错误—SharePoint管理框架中的对象“SPSolutionLanguagePack Name=0”依赖其他不存在的对象
    Elevate Permissions To Modify User Profile
    Error with Stsadm CommandObject reference not set to an instance of an object
    ASP.NET MVC3添加Controller时没有Scaffolding options
    测试使用Windows Live Writer写日志
    配置TFS 2010出现错误—SQL Server 登录的安全标识符(SID)与某个指定的域或工作组帐户冲突
    使用ADO.NET DbContext Generator出现错误—Unable to locate file
    CSS
    HTML DIV标签
    数据库
  • 原文地址:https://www.cnblogs.com/slmk/p/2406429.html
Copyright © 2011-2022 走看看