在.NET中,使用指针作为函数参数或使用“ref”关键字有什么区别吗?

时间:2012-04-19 13:40:30

标签: .net pointers struct unsafe ref

我编写了一个结构和函数,我尝试通过引用传递结构(即可以在函数内修改结构值)。

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);
    }
}

现在通过引用传递这个结构我发现了两种方法。

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

//Using ref keyword.
private static void Reserve(ref HotelRoom room)
{
    if (room.Taken)
         Console.WriteLine("Cannot reserve room {0}", room.Number);
    else
         room.Taken = true;
}    

有什么区别吗?一般情况下,何时应该使用指针,何时应该使用ref关键字?

4 个答案:

答案 0 :(得分:3)

简单的经验法则:

  

不要使用指针。

指针用于模糊互操作或钝化优化 通常,您不应使用不安全的代码。

答案 1 :(得分:1)

指针被认为是不安全的。

如果您在不安全的上下文中编写代码,比如通过指针将引用传递给函数,有人可以将指针更改为指向其他位置的指针,并获得垃圾数据。

如果您使用ref关键字,则上下文是“安全的”,并且您无法更改房间指向的位置,只能更改数字,< strong>采取和类别

答案 2 :(得分:1)

指针是C#语言的有用部分。使用指针并不困难,但应谨慎使用,因为它可能导致错误的诊断难度。使用指针会干扰垃圾收集器功能,尤其是当我们在程序中使用许多指针时。因此,在使用指针之前,我们应该考虑它并尝试寻找其他方法。有关详细信息,请参阅:http://www.c-sharpcorner.com/UploadFile/gregory_popek/WritingUnsafeCode11102005040251AM/WritingUnsafeCode.aspx

Working with pointers in C#

答案 3 :(得分:0)

在.net中,当ref传递某些内容时,被调用的函数会收到一个指针,除非在某些非常有限的情况下,否则它将被禁止复制;除非指针被赋予unsafe代码,否则在被调用函数返回之前,保证在执行被调用函数期间生成的指针的任何副本都被销毁。如果有问题的指针指向堆对象的一部分,与调用站点关联的元数据将让垃圾收集器知道在哪里找到对该对象的引用,以便它知道不会打扰它。

unsafe函数或非托管代码创建或传递的指针是不同的。如果不安全的函数或非托管代码具有指向某个东西的指针,它可以以比函数调用更长的方式存储它,垃圾收集器不知道该方式。有一种方法可以明确地告诉垃圾收集器不要打扰堆对象,但是这种技术的使用充满了危险。

使用ref按引用传递参数,除非有极其强烈的理由使用指针。在两种技术都能正常工作的情况下,它的传递速度与传递指针一样快。