【问题标题】:In .NET is there any difference between using pointers as function parameters or using the "ref" keyword?在 .NET 中,使用指针作为函数参数或使用“ref”关键字有什么区别吗?
【发布时间】:2012-05-01 01:01:07
【问题描述】:

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

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 关键字?

【问题讨论】:

  • 可变结构是邪恶的。您应该使用一个类和一个普通参数。
  • 带指针的unsafe关键字需要告诉你你的问题是什么?
  • 听起来你在用 C++ 术语思考。别。 C# 不是 C++。
  • @SLaks jsut 试图利用 .Net 的所有优化选项,我已经用 C++ 编码超过 10 年,所以可能会有一些效果。
  • 这不是优化;这实际上是一种悲观。固定是众所周知的impair GC performance

标签: .net pointers struct unsafe ref


【解决方案1】:

简单的经验法则:

不要使用指针。

指针用于模糊互操作或模糊优化。
一般来说,你不应该使用不安全的代码。

【讨论】:

  • 同意。在.Net 中不需要使用指针。这就是refout 的用途。但是,如果您在项目中包含非托管代码,则可能需要使用指针。这就是存在此选项的原因。
  • @Nico Schertler 2 个地方 2 被使用。 1) 互操作 2) 优化。
  • @Pritesh:但是,在少数情况下指针实际上会使事情变得更快。一般来说,如果你不得不问,你可能不应该问。 (并且一如既往地测量!)
  • @SLaks 这就像“使用指针的力量伴随着巨大的责任”
【解决方案2】:

指针被认为是不安全的。

如果您在不安全的上下文中编码,例如通过指向函数的指针传递引用,则有人可以将您的指针更改为其他地方的指针,并且您会得到垃圾数据。

如果你使用 ref 关键字,上下文是“安全的”,你不能改变 room 指向的位置,只能是 number 之类的数据,采取和类别

【讨论】:

  • 您提出的最重要的一点是“有人可以将您的指针更改为其他地方的指针,然后您会得到垃圾数据”+1?
  • 你问我要不要 +1?我有偏见.. :)
  • 我把“?”因为失误。它是“+1”,你的回答非常好。
【解决方案3】:

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

Working with pointers in C#

【讨论】:

  • 似乎 Hammer 必须在某个时候使用它,但要小心,不应该最终击中我们自己的脚。
【解决方案4】:

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

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

使用ref 通过引用传递参数,除非有非常充分的理由使用指针。在两种技术都能正常工作的情况下,它往往与传递指针一样快。

【讨论】:

    猜你喜欢
    • 2014-04-28
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 2020-05-18
    • 2015-02-07
    • 2011-08-28
    相关资源
    最近更新 更多