Reputation: 11317
Say I have this C# class:
public class HttpContextEx
{
public HttpContext context = null;
public HttpRequest req = null;
public HttpResponse res = null;
}
How do I declare an object of it, inside a function, which will be allocated on the stack and not on the heap?
In other words I want to avoid using the 'new' keyword for this one. This code is bad:
HttpContextEx ctx = new HttpContextEx(); // << allocates on the heap!
I know what stack/heap are perfectly and I've heard of the wonderful C# GC, yet I insist to allocate this tiny object, which is here only for convenience, on the stack.
This attitude comes from C++ (my main tool) so I can't ignore this, I mean it really ruins the fun for me here (:
Upvotes: 12
Views: 11082
Reputation:
The short answer is that C# doesn't support what you are seeking to do.
The object that you are referring to is a class (reference type) and it also contains members that are class types. Memory for class instances is in the managed heap and use of the stack for class instances isn't supported.
"...reference types are allocated on the heap and garbage-collected..."
https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/choosing-between-class-and-struct
However, you could change your class to a ref struct such that at least the references to its members will be on the stack (although the member instances will be on the heap):
public ref struct HttpContextEx
{
public HttpContext context = null;
public HttpRequest req = null;
public HttpResponse res = null;
}
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/ref-struct
As an aside, additional C# stack capabilities:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/stackalloc
Upvotes: 1
Reputation: 10789
If you changed it to a value type using struct
and create a new instance within the body of a method, it will create it on the stack. However the members, as they are reference types will still be on the Heap. The language whether it be a value or a reference type will still require the new operator but you can use var
to eliminate the double use of the type name
var ctx = new HttpContextEx();
Otherwise, take C# as it is since the GC does a great job.
Upvotes: 18
Reputation: 700432
In .NET classes are reference types, and structures are value types.
If you really want the type allocated on the stack, you can make a structure. There are however several reasons not to:
Finally, there isn't anything inherently bad about allocating small objects on the heap. The memory manager is actually specifially designed to handle small short-lived objects efficiently.
Here is an example of code that doesn't work if it's a structure, but works fine if it's a class:
public void SetContext(HttpContextEx ex) {
ex.context = HttpContext.Current;
ex.req = ex.context.Request;
ex.res = es.context.Response;
}
HttpContextEx ctx = new HttpCoontextEx();
SetContext(ctx);
Upvotes: 2
Reputation: 61457
You can't (and shouldn't) do that. Even if you would use a struct
(which will be put on the stack), you'd have to use the new
operator for the contained classes. On a serious note, if you switch to another language, also switch your attitudes.
Upvotes: 10
Reputation: 27419
You must come from C++. Things don't work like that in .Net.
All reference types are allocated on the managed heap, where they are tracked by the GC. For object references scoped by a function which exits quickly, allocated objects most likely remain only in Generation 0 of the Managed Heap, and this results in very efficient memory collections. The Managed Heap is tuned to handle short lived objects like this. It doesn't even have the same allocation strategy as the C++ heap you may be used to.
This is how the CLR works. If you want to work in another way, try an unmanaged runtime.
Upvotes: 3