2012-04-19 27 views
1

当需要固定块时,我有点困惑。我有例子,给了我下面的一个矛盾的情形:固定块in .net

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])。我认为他们正在做同样的事情 - 将HotelRoom结构的存储地址传递给Reserve函数。为什么我需要fixed来做到这一点?

回答

1

Room是存储在堆栈中的局部变量,而myfloor存储在堆中。垃圾收集器可以移动堆中的对象来压缩它(地址会改变),所以你需要“钉住”它们。这就是为什么你需要fixed声明。

更新:

此外,还有是在栈上分配内存的方式insted的堆:

HotelRoom* fib = stackalloc HotelRoom[4];

在这种情况下,你将不再需要fixed声明。

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

+0

得到了我完全错过了这一点..你immdeiately指出。谢谢。 – Pritesh 2012-04-19 12:10:43

1

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

或...

我猜你想改写C++为C#。你很少需要使用unsafe,.NET的主要观点是它是一个托管框架。除非我在这里完全错误(所有的代码都可以写成托管代码),您应该了解非托管代码和托管代码之间的区别,尤其是如何编写来自C++背景的C#。

看一看这些:

what is the difference between “managed” vs “unmanaged”?

Difference between Managed Code and Unmanaged Code?

C# for C++ Developers

.NET Book Zero

(从C# books or web sites for C++ developers [closed]编辑)

+0

你猜对了我也有C++ bagrounds。我想知道我可以通过uisng ref关键字来传递参数。在C#中,有时候我们需要指针,我注意到的是一个实例。假设我想要实现字符串反转,那么只有我能想到的是。使用系统的 – Pritesh 2012-04-19 12:17:34

+0

; 类测试{ \t私人不安全静态无效反向(文本串){ \t \t固定的(字符* PSTR =文本){ \t \t \t字符* pBegin = PSTR; \t \t \t char * pEnd = pStr + text.Length - 1; \t \t \t而(pBegin Pritesh 2012-04-19 12:17:41

+0

链接提供了有关托管/ unmanged代码的好主意。我想知道如果unmanged代码不推荐,为什么微软保持它在.net framewrok? – Pritesh 2012-04-19 12:39:07