在.NET固定块(fixed block in .net)

2019-10-16 15:16发布

我当需要固定块上有点混乱。 我有例子,给了我以下矛盾的情形:

enum RoomType { Economy, Buisness, Executive, Deluxe };

struct HotelRoom
{
    public int Number;
    public bool Taken;
    public RoomType Category;

    public void Print()
    {
        String status = Taken ? "Occupied" : "available";
        Console.WriteLine("Room {0} is of {1} class and is currently {2}", Number, Category, status);
    }
}

我做了这将需要一个指向一个函数HotelRoom

private unsafe static void Reserve(HotelRoom* room)
{
    if (room->Taken)
        Console.WriteLine("Cannot reserve room {0}", room->Number);
    else
        room->Taken = true;
}

在main方法我有以下几点:

unsafe static void Main(string[] args)
{
    HotelRoom[] myfloor = new HotelRoom[4];
    for (int i = 0; i < myfloor.Length; i++)
    {
        myfloor[i].Number = 501 + i;
        myfloor[i].Taken = false;
        myfloor[i].Category = (RoomType)i;
    }
    HotelRoom Room =  myfloor[1];
    Reserve(&Room);   //I am able to do this without fixed block.
    //Reserve(&myfloor[1]);  //Not able to do this so have to use fixed block below. 

    fixed (HotelRoom* pRoom = &myfloor[1])
    {
        Reserve(pRoom);
    }

    myfloor[1].Print();
    Room.Print();
}

我的困惑是,我能够做到Reserve(&Room) ,但没有Reserve(&myfloor[1]) 我认为他们正在做同样的事情-传递的memeory地址HotelRoom结构的Reserve功能。 为什么需要fixed做到这一点?

Answer 1:

Room是被存储在堆栈中,而一个局部变量myfloor存储在堆。 垃圾收集器在堆中移动对象,以压缩它(不会忽略会改变),所以你需要“针”他们。 这就是为什么你需要fixed说法。

更新:

此外,还有一种方法可以在栈上分配存储器insted的堆:

HotelRoom* fib = stackalloc HotelRoom[4];

在这种情况下,你将不再需要fixed说法。

小disclamer:能够做到这一点并不意味着你当然应该。 正如其他人已经提到的,它是写代码很non-.NET的方式,所以我认为这个问题是理论上的。



Answer 2:

这仅仅是一个扔掉的例子吗?

要么...

我猜你想改写C ++为C#。 你很少需要使用unsafe ,.NET的主要观点是,它是一个管理框架。

除非我完全错了这里(所有的代码可以写成托管代码),你应该在非托管和托管代码之间的差异读了起来,特别是如何编写C#从C ++背景的。

看看这些:

之间有什么“管理”与“非托管”的区别?

托管代码和非托管代码之间的区别是什么?

C#C ++开发

.NET图书零

(从编辑C#书籍或网站C ++开发[闭合] )



文章来源: fixed block in .net