@Fooberichu's answer is spot on, but I think it's also worth pointing out that usually only a few things "need" to be explicitly disposed.
Objects are always effectively disposed at some point:
- Any time the GC does a collection, it will (eventually) dispose of objects that are no longer referenced. So if you don't manually dispose, the object may still be disposed within a few seconds of it going out of scope.
- When your application quits, all resources it held are released. (Although the objects may not be disposed by C#/.net, the OS will claim back pretty much anything your process grabbed. If the lifetime of the resource extends beyond your application, then the OS is usually responsible for cleaning it up)
The point of manually disposing (or employing a 'using') is therefore not to ensure that the resources will be released, but to release them as early as possible.
These days you are unlikely to run out of most types of resources (e.g. memory, file handles, or system brushes). However, if you hold on to resources when you don't need to, your program is likely to be less efficient, you might use more memory than necessary, or perhaps cause delays by temporarily blocking other applications from doing useful things, etc. In general, then, Disposing is about good etiquette, tidiness and cutting out unnecessary inefficiencies.
There are a few cases where resources must be released (e.g. if you don't close a file, you can't open/rename/move/delete it from elsewhere in your program or other programs; if you keep allocating textures on your graphics card without releasing them, you'll run out of VRAM and the computer's display will fail), but in general, you will encounter these situations infrequently, and if you follow best practices (explicitly disposing objects when they're no longer needed), you won't usually need to know when these situations are occurring because you'll already be dealing with them correctly.