【问题标题】:Is a static member movable or fixed anyway?静态构件是可移动的还是固定的?
【发布时间】:2011-10-16 18:06:59
【问题描述】:

在另一个topic 中,一位好人引用 Eric Lippert 的话告诉我:静态的意义与编译器在编译某个类/结构/字段时所拥有的知识和确定性有关。它与内存位置以及它们是否固定等无关。

但我还是不太确定,因为编译器允许发生如下所示的事情。

        struct MyStruct
        {
             public static int[] Arr = {1,3,5};
        }
        static void Test<T>(ref T t) where T:struct
        {
            Console.WriteLine (t);
        }
        void Main()
        {
            Test(ref MyStruct.Arr[2]);//output: as expected 5
        }

与 c++ 引用相比,ref 参数是否完全不同,或者每次 ref 传递一些 args 时都会发生幕后引脚?如果静态成员是可移动的,那么运行时如何保证数组元素的地址在被调用函数执行期间不会改变?我从一个实验中了解到,对象的“Item prop 除了数组”的返回值是不允许通过 byRef 传递的。我以为是因为数组元素被分配在一块连续的内存中,但是如果整个数组是可移动的,那么如何获取其元素的地址呢?

我有点被这种不确定性所困扰。如果有人能给出一些确定的答案,我将不胜感激。提前致谢!

~~~~~~~~~~~~~~~~~~

试图理解它:

所以,只要编译器允许,任何托管操作都不会发生,我们不应该为此而烦恼,对吧?我有一些 C/C++ 背景,我想我非常了解 C++ 中“静态”的含义,只有托管代码的可移动性让我怀疑。任何托管对象,无论是在栈上还是托管堆上,A ref arg 总能正确指向它,对吧?

【问题讨论】:

  • 您会感到困惑,因为静态应用于成员函数时的含义与应用于占用内存的对象成员时不同。 The quote from Mr. Lippert 仅指方法。
  • 无论如何,如果一个对象被重新定位,所有对该对象(以及其中包含的对象)的引用也将被更新。这就是为什么它们是参考,而不是地址。

标签: c# byref


【解决方案1】:

C# ref 参数与 C++ 引用并没有完全不同,但它们在这方面有所不同。

垃圾收集器知道 C# ref 参数,如果它将对象提升到不同的代,它将调整它们。

C++ 引用对 .NET 垃圾收集器是不可见的,如果目标未固定且垃圾收集器运行,它们将中断。

(C++/CLI 支持 .NET 引用和本机引用)

如果静态成员是可移动的,那么运行时如何保证数组元素的地址在被调用函数执行过程中不会改变?

它没有。但是该函数将使用更新后的地址,因为它也是.NET代码。

并且这些都不会根据是否存在引用数组的静态字段而改变。 (实际上数组本身不是静态的,只有引用它的字段。这一事实使整个问题变得荒谬。)

【讨论】:

  • 每当引用的对象被移动时,它们会被调整吗?我说对了吗?谢谢!
猜你喜欢
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-31
相关资源
最近更新 更多