Due to the overhead of calling the garbage collector in the CLR, is it more efficient to leave it, or force to garbage collection when objects go out of scope?
Most of the time, it's not worth it to manually call the garbage collector. You would be surprised at how much efficient the underlying garbage collector algorithm is.
Unless if you are working in financial application (e.g: derivative trading application) that requires you to have full control of the time when garbage collector gets called. But if you are going into that route maybe you should try other language, such as C++
The people that wrote .NET and the Garbage Collector put a lot of thought into it so you don't have to. Just call dispose on your objects when applicable and don't worry about the rest.
One of the main reasons not to call the GC yourself is that since the GC is self-tuning, any calls you make to collect from the managed heap will effectively destroy any of the self-tuning that the GC has done on your application's behalf.
One of the main things that the GC will do is adjust the thresholds that trigger garbage collection on each of the three generations of the managed heap to reduce the number of collections that are needed for your application.
For all but extreme cases it is best to allow the GC to do its job and not worry about invoking it manually. Only when you have identified a clear need should you manually invoke a collection.
In addition to Andrew's comments, unnecessarily calling GC.Collect will cause otherwise efficient Gen-0 collections to be pushed into Gen-1 and Gen-2 buckets which are collected far less frequently. Ironically, this means your application will suffer from increased longer-term memory usage, defeating the original intention of reducing memory usage.
One of the few cases where calling GC.Collect is necessary would be when interoping with COM or Win32. For example, it's not uncommon for COM objects in Office to hang around longer than intended because there is no way to explicitly dispose them. Therefore you might want the COM wrappers to be GC'd at a specific time and usually that would be followed up with a call to WaitForPendingFinalizers.