I have written a struct and functions where I try to pass the struct by reference (i.e. struct value can be modified inside functions).
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);
}
}
Now to pass this struct by reference I've found two ways.
//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;
}
Is there any difference? In general when should I use a pointer and when should I go for the ref keyword?
Pointers are considered unsafe.
If you code in an unsafe context, like passing a reference by pointer to the function, someone can change your pointer to pointer somewhere else, and you get garbage data.
If you use the ref keyword, the context is "safe", and you can't change where room is pointing to, only it's data like number, taken and category.
Simple rule of thumb:
Don't use pointers.
Pointers are meant for obscure interop or obtuse optimizations.
In general, you should not use unsafe code.
Pointers are useful part of C# language. Using pointers are not difficult but should be used carefully because it might be cause of errors difficult to diagnose. Using pointers disturb garbage collector functioning especially when we use many pointers in our program. Therefore before using pointers we should consider it and maybe try to find some other ways.For details see:
http://www.c-sharpcorner.com/UploadFile/gregory_popek/WritingUnsafeCode11102005040251AM/WritingUnsafeCode.aspx
and
Working with pointers in C#
In .net, when something is passed by ref
, the called function receives a pointer which it is forbidden from copying except in certain very limited circumstances; unless the pointer is given to unsafe
code, any copies of the pointer that have been made during the execution of the called function are guaranteed to be destroyed before the called function returns. If the pointer in question points to part of a heap object, the metadata associated with the call site will let the Garbage Collector know where to find a reference to that object, so that it will know not to disturb it.
Pointers created by, or passed to, unsafe
functions or unmanaged code are different. If an unsafe function or unmanaged code has a pointer to something, it may store it in a fashion which outlives the function call, and which the Garbage Collector doesn't know about. There exist means by which the Garbage Collector can be explicitly told not to disturb a heap object, but the use of such techniques is fraught with peril.
Use ref
for passing parameters by reference unless there's an overwhelmingly strong reason to use pointers. It's apt to be just as fast as passing pointers in cases where both techniques will consistently work correctly.