Wie Jürgen schon geschrieben bzw. verlinkt hat: das Objekt wird automatisch (aber im allgemeinen irgendwann) vom Garbage Collector aufgeräumt, wenn es nicht mehr referenziert wird. In Deinem Beispiel würde das von alleine geschehen, wenn p aus dem Scope geht. Wenn Du ganz eifrig sein willst oder wenn p eine Membervariable ist, dann setzt Du p gleich null (oder auf irgendein anderes Objekt vom passenden Typ, das Du noch brauchst). Ebenso mit allen anderen Variablen, die das Objekt noch referenzieren. Pass insbesondere auf mit Event-Registrierungen: so lange eine solche besteht, referenziert der Event-Publisher den Event-Subscriber.
Sonst ist von Programmiererseite her nur dann noch etwas zu tun, wenn die Klasse des Objekts die Schnittstelle IDisposable implementiert. Dann solltest Du Dispose() aufrufen, sobald Du das Objekt nicht mehr brauchst, damit vom Objekt verwendete Ressourcen so früh als möglich freigegeben werden und nicht erst, wenn der Garbage Collector irgendwann mal in Aktion tritt. Am einfachsten (und hinsichtlich Exceptions auch am robustesten) geht das über ein using-Konstrukt:
using (var p = new MyClass()) { //irgendwas mit p anstellen
} //beim Verlassen des Blocks wird automatisch p.Dispose() aufgerufen