C# 使用固定语句获取托管对象的地址

C# 使用固定语句获取托管对象的地址,c#,pointers,unsafe,C#,Pointers,Unsafe,从 fixed语句防止垃圾收集器重新定位可移动变量 fixed语句设置指向托管变量的指针,并在语句执行期间“固定”该变量。如果没有固定的,指向可移动托管变量的指针将没有什么用处,因为垃圾收集可能会不可预测地重新定位变量。C#编译器只允许在固定语句中为托管变量分配指针 为什么不允许我直接创建指向托管变量的指针(下面的示例代码) 使用系统; 类点 { 公共int x; 公共智力; 公共点(int xx,int yy) { x=xx; y=yy; } 公共重写字符串ToString() { 返回str

fixed语句防止垃圾收集器重新定位可移动变量

fixed语句设置指向托管变量的指针,并在语句执行期间“固定”该变量。如果没有固定的,指向可移动托管变量的指针将没有什么用处,因为垃圾收集可能会不可预测地重新定位变量。C#编译器只允许在固定语句中为托管变量分配指针

为什么不允许我直接创建指向托管变量的指针(下面的示例代码)

使用系统;
类点
{
公共int x;
公共智力;
公共点(int xx,int yy)
{
x=xx;
y=yy;
}
公共重写字符串ToString()
{
返回string.Format(({0},{1})”,x,y);
}
}
班级计划
{
静态void TestPointRef()
{
点p=新点(3,5);//创建一个新点实例
不安全的
{

固定(点*pp=&p)//C#语言强烈限制了您可以使用的指针类型,它不允许指向托管引用类型的指针。在这种情况下,您可以通过将点声明为结构来取得成功。在这种情况下,您会注意到,在这个代码段中也不再需要fixed,因为
p
已经位于固定位置。@HansPassant我明白了,当点被声明为结构时,不需要fixed的原因是
p
在堆栈上分配(因此不受GC的约束)?是的,方法参数和局部变量有固定的位置。静态变量也有固定的位置,但C#不知道。对于静态,需要fixed,一个点的元素[]数组或如果点是类的字段。谢谢你的帮助!@HansPassant:我不理解你的评论…在问题的上下文中(在
固定的
语句中)说“C语言[…]不允许指向托管引用类型的指针”似乎与MSDN语句相矛盾“C#编译器只允许您在固定语句中为托管变量分配指针”。因此,这个问题似乎还没有得到回答(我实际上在试图理解为什么指针可以设置为
p.x
,一个值类型
int
,而不是
p
,一个参考类型
(MSDN似乎也允许这样的情况)。
using System;

class Point
{
    public int x;
    public int y;

    public Point(int xx, int yy)
    {
        x = xx;
        y = yy;
    }

    public override string ToString()
    {
        return string.Format("({0}, {1})", x, y);
    }
}

class Program
{
    static void TestPointRef()
    {
        Point p = new Point(3, 5); // Create a new Point instance

        unsafe
        {
            fixed(Point* pp = &p) // <- This is not allowed
            {
                Console.WriteLine(*pp);
            }
        }
    }

    static int Main(string[] args)
    {
        TestPointRef();
        return 0;
    }
}