Сходство есть, но и различий достаточно. Указатель хранит адрес в памяти, который в общем-то доступен вам для чтения и записи. Вы можете любой int скастить в указатель и попытаться разыменовать его. Врядли ли вы получите от этого что-то полезное, но суть в том что вы МОЖЕТЕ это сделать. Указатель как тип данных лишь даёт вам удобное средство для адресации и типизированной работы с областью памяти.
Ссылка в .net - вещь значительно более высокоуровневая. Это скорее object identity, а не адрес в памяти. Ссылка не хранит непосредственно адрес объекта в управляемой куче, она хранит его номер, а конкретным адресом в памяти управляет сборщик мусора (так сделано потому, что сборщик имеет право перемещать объекты в памяти, если они явно не закреплены).
Как уже сказали выше, указатели в C# тоже есть, и они действительно хранят адрес. Но они доступны только в unsafe контексте и не являются средством для everyday-разработки.
Ссылки в C# концептуально связаны с объектным подходом, ссылка хранит идентификатор объекта и является "ключом" доступа к нему. Ссылка не может непосредственно ссылаться на типы-значения на уровне платформы .net, для этого нужно сначала выполнить boxing значения.
Сишкном указателю же без разницы, на что он указывает. Если говорить в контексте C++, то программист по сути сам даёт указателям на объекты семантику object identity.