在另一个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时,场景引脚会发生吗?如果静态成员是可移动的,那么运行时如何保证在执行被调用函数期间数组元素的地址不会改变?我从一个实验中了解到,不允许通过byRef传递对象'Item prop而不是数组'的返回值。我认为那是因为数组元素被分配在一块连续的内存中,但是如果整个数组是可移动的,那么如何获取其元素的地址呢?
我有点被这种不确定性所困扰。如果有人能给出一定的回答,我将非常感激。提前谢谢!
~~~~~~~~~~~~~~~~~~
试图理解它:
所以,任何托管操作只要编译器允许它发生,我们就不应该流汗吧?我有一些C / C ++背景,我认为我很清楚c ++的“静态”的含义,只有托管代码的可移动性让我怀疑。任何托管对象,无论是在堆栈还是托管堆上,参考arg总能正确指向它,对吗?
答案 0 :(得分:4)
C#ref参数与C ++引用并没有完全不同,但它们在这方面有所不同。
C#ref参数对于垃圾收集器是已知的,如果它将对象提升到不同代,它将调整它们。
C ++引用对于.NET垃圾收集器是不可见的,如果目标没有固定并且垃圾收集器运行,它们将会中断。
(C ++ / CLI支持.NET引用和本机引用)
如果静态成员是可移动的,那么运行时如何保证在执行被调用函数期间数组元素的地址不会改变?
没有。但该函数将使用更新的地址,因为它也是.NET代码。
并且这些都不会改变,这取决于是否存在引用该数组的静态字段。 (事实上,数组本身并不是静态的,只有引用它的字段。这一事实使整个问题变得荒谬。)