There is a slight, yet extremely important, distinction between a pointer and a reference. A pointer points to a place in memory while a reference points to an object in memory. Pointers are not "type safe" in the sense that you cannot guarantee the correctness of the memory they point at.
Take for example the following code
int* p1 = GetAPointer();
This is type safe in the sense that GetAPointer must return a type compatible with int*. Yet there is still no guarantee that *p1 will actually point to an int. It could be a char, double or just a pointer into random memory.
A reference however points to a specific object. Objects can be moved around in memory but the reference cannot be invalidated (unless you use unsafe code). References are much safer in this respect than pointers.
string str = GetAString();
In this case str has one of two state 1) it points to no object and hence is null or 2) it points to a valid string. That's it. The CLR guarantees this to be the case. It cannot and will not for a pointer.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…