zoukankan      html  css  js  c++  java
  • C#中引用变量是否应该加ref?

    看如下代码:
     
    void Test(T t);
    void Test(ref T t);
    当T是值类型的时候,很好判断,第一种并不能改变方法外变量的值,需要第二种方法才可以。通过查看IL代码,可以看到第二种方法是直接传的原变量T的地址,这里并没有发生装箱行为(如果发生装箱的话,会在堆中新建一个T变量,这也不会改变原来T变量的值,因此不成立)。
    当T是引用类型的时候,第一种其实也相当于值传递,不过是原变量的地址给了t这个变量,最终操作的是同一个对象。而用ref的话,就没有地址复制这一步,直接把原变量的地址传了进去,当然结果都是一样的。
     
    *但如下情况需要注意的是
     
            static void Main(string[] args)
            {
                UserInfo info = new UserInfo();
                Console.WriteLine("调用方法之前哈希code:{0}", info.GetHashCode());
                Reset(info);
                Console.WriteLine("调用方法之后哈希code:{0}", info.GetHashCode());
                Console.ReadKey();
            }
     
            public static void Reset(UserInfo info)
            {
                Console.WriteLine("Reset赋值之前的哈希code:{0}", info.GetHashCode());
                UserInfo user = new UserInfo();
                info = user;
                Console.WriteLine("Reset赋值之后哈希code为{0}", info.GetHashCode());
            }
    查看输出:
     
    可以看到,如果不使用ref,传入的是引用的一个副本,这个副本存储的地址和传入的变量是一致的,引用同一个对象,因此哈希值相同。
    给这个副本赋新的变量地址后,哈希值发生了改变。
    但这总归是发生在复制的副本身上,原来的变量,哈希值未改变。
    值得注意的是,如果info里面的参数,在Reset中info = user这个语句之后,发生了任何改变,都已经不会体现到Reset外围。
    比如info.userName = "aa";
    在info = user语句之后,加入 info.userName = "cc"。
    在最后Console.ReadKey之前输出userName, 它还是"aa"。
    Reset里面的info已经完全指向另外一个对象了。
     
    如果我们在Reset方法的参数之前加上ref
     
    那就是直接使用外围变量的值了,任何操作都直接影响外围传入的变量。包括上述说的userName也会被改变。整个来说就是原来变量地址上的类被换了一个。
     
    综合来说,如果只是改变原有变量的内部变量值之类的操作,加不加ref都一样,当涉及到new赋值操作的时候,除非是刻意需要这么做,不然推荐加ref。
  • 相关阅读:
    REST Security with JWT using Java and Spring Security
    UserMapper.selectByPrimaryKey-Inline 报错的解决办法
    Nginx反向代理,负载均衡,redis session共享,keepalived高可用
    HTML 5 Web 存储-localStorage
    Android之自定义checkbox样式
    android fragment传递参数_fragment之间传值的两种方法
    linux常用基本命令
    fragment点击跳转到外部Activity后,怎么通过返回按钮返回
    android 中FragmentActivity中模拟返回键返回上一个Activity效果
    Fragment与Activity相互传递数据:
  • 原文地址:https://www.cnblogs.com/cangxw/p/8487699.html
Copyright © 2011-2022 走看看