Because C# works on garbage collection for memory safetiness, as opposed to C++, were you are expected to know neuances of memory management.
for example, take a look at the next code :
public static void doAsync(){
var arr = stackalloc string[100];
arr[0] = "hi";
System.Threading.ThreadPool.QueueUserWorkItem(()=>{
Thread.Sleep(10000);
Console.Write(arr[0]);
});
}
The program will easly crash. because arr
is stack allocated, the object + it's memory will disappear as soon as doAsync
is over. the lamda function still points to this not-valid-anymore memory address, and this is invalid state.
if you pass local primitives by reference , the same problem will occure.
The schema is:
static objects -> lives throughout the applocation time
local object -> lives as long as the Scope that created them is valid
heap-allocated objects (created with new
) -> exist as long as someone hold a reference to them.
Another problem with that is that the Garbage collection works in periods. when an object is local, it should be finalized as soon as the function is over , because after that time - the memory will be overriden by other variables.
The GC can't be forced to finalize the object, or shouldn't, anyway.
The good thing though, is that the C# JIT will sometimes (not always) can determine that an object can be safetly be allocated on the stack, and will resort to stack allocation if its possible (again, sometimes).
In C++ on the other hand, you can declare everything enywhere, but this comes with less safetyness then C# or Java, but you can fine-tune you application and achieve high performance - low resources application