C# was designed to simplify memory management to provide programmers which is a quicker and easier way to program. That comes at the cost of performance (and lazy programming) as a garbage disposal has to come by and kill all the broken pointers. For instance, in a game update loop this creates a lot of stuff for the garbage disposal to collect:
Vector3 myVector;
void update(int x, int y, int z)
{
myVector = new Vector3(x, y, x); //This will kill your Xbox 360 with enough objects
}
In c# everything is held as a reference. This is a bit different from C/C++ where the programmer has different ways referencing data in RAM.
As a way to provide more flexibly to programmers, especially in areas which require high performance, a programmer is allowed to use pointers and references. This is called "unsafe" variables because it is no longer managed by the garbage disposal. In other words, if there is a memory leak, the garbage disposal will not come by and delete it.
Another reason is for compatibility between C#/C++. If you get into interpolating code between the two languages, you will quickly realize that C# needs to know how to provide compatibly for pointers being passed and obtained by the C++ side. So say if I want to pass C++ code a pointer, I pass
someInterpatedFunc(ref myVariable);
Hope that answers some questions :)