【问题标题】:Passing a value using the ref keyword使用 ref 关键字传递值
【发布时间】:2013-12-31 09:08:18
【问题描述】:

阅读the MSDN article on the ref keyword 后,我对使用 ref 关键字传递值类型时 C# 的作用感到困惑。文档指出 ValueTypes 没有装箱。我的问题是 C# 如何处理将值类型作为引用传递?它是否将一些副本传递给在堆栈上分配的数据?谢谢。

【问题讨论】:

标签: c# parameters ref


【解决方案1】:

它是否将一些副本传递给在堆栈上分配的数据?

不,它不会复制。 refout 关键字可以比作 C 中的指针传递或 C++ 中的引用传递,当变量的内存位置(即地址)传递给目标方法时。然后,接受引用的方法将使用传入的内存位置直接修改该值。

知道变量是通过引用传递的,编译器插入将ref变量视为地址的指令,允许就地修改。

【讨论】:

    【解决方案2】:

    tl;dr:拳击不是“你如何创建参考”;它是“您如何为不期望该确切类型的消费者打包原始值类型”。

    在 .NET 中,引用类型是堆上的类实例。 intdouble 之类的值类型只是字节:32 位 int 只是四个字节的 0 和 1。当你把它放进去时,说一个System.List(老式的前通用类型,Granpaw 在杂货店里删掉了),然后把它拿出来,如果你调用 GetType,编译器怎么知道该怎么做() 在上面?它只有四个字节......什么?谁知道?如果它在List 中存储了一个指针,它将有一个指向四个字节的指针...谁知道呢?

    在您自己的方法中,生成的代码知道您的变量是什么。定期强类型检查。但是,当您将变量的值发送给只知道他在期待Object 的其他人时,这不起作用。

    因此,当您将int 添加到List 或将其传递给以Object 作为参数的函数时,编译器必须向其中添加一些信息,以便其他人知道他得到了什么。

    所以“装箱”意味着将一个非引用值打包到一个可以被视为Object 实例的对象中。对于普通的ref 参数,这不是必需的,因为类型是完全已知的:为函数内部生成的代码不必准备处理任何任意引用类型。它知道它正在获取(例如)一个指向整数的指针,这就是它所要获取的全部内容。 Boxing 提供了在这种情况下不需要的功能,因此编译器不会浪费用户的周期。

    装箱并不是唯一引用(在术语的最广泛意义上)例如double 的方式。相反,装箱是将double 视为可以存储在System.List 中的对象的唯一方法:它必须在堆上,必须可转换为Object,必须具有运行时类型信息等。

    对于以下情况,所有调用者或被调用者都需要64 zeroes and ones某处的地址:

    void f(ref double d) { d *= 2; }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-13
      • 2010-12-13
      • 2012-11-19
      • 2017-02-11
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多