C
C#7mo ago
MikeS++

A way to store references or pointers to objects in arrays/lists?

Is there a way to do the following code, which is written in c++, in c#? Assume those variables cannot be inside the array, but have to stay where they are declared somewhere in some class.
c++
int a = 1;
int b = 2;
int c = 3;

std::vector<int*> ListOfVariableReferences;
ListOfVariableReferences.push_back(&a); // Adds the address of a to the list.
ListOfVariableReferences.push_back(&b); // Adds the address of b to the list.
ListOfVariableReferences.push_back(&c); // Adds the address of c to the list.

*ListOfVariableReferences[0] = 5; // Changes the value of the variable a declared at the top
c++
int a = 1;
int b = 2;
int c = 3;

std::vector<int*> ListOfVariableReferences;
ListOfVariableReferences.push_back(&a); // Adds the address of a to the list.
ListOfVariableReferences.push_back(&b); // Adds the address of b to the list.
ListOfVariableReferences.push_back(&c); // Adds the address of c to the list.

*ListOfVariableReferences[0] = 5; // Changes the value of the variable a declared at the top
13 Replies
wasabi
wasabi7mo ago
No. Variables are on the stack. Arrays are on the heap. You cannot have a valid reference to a value on the stack reside on the heap.
MikeS++
MikeS++7mo ago
so any advice on what that can be substituted with?
Jimmacle
Jimmacle7mo ago
you could wrap a value type in a reference type classes are always handled by reference basically manual boxing
PixxelKick
PixxelKick7mo ago
in C#, "refs" are inherent to the variables themselves, you dont have to manually control the allocation of pointers, simply passing the variable around into methods will suffice. Specifically, this documentation will help you with which variables by default are passed in by ref vs by val (equivalent to how pointers work in C++) Basically C# just automatically handles the pointers for you, as well as garbage collection by extension. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/method-parameters
PixxelKick
PixxelKick7mo ago
in your case specifically, if you want to pass a value type (typically a struct) by reference, you do it via the ref operator, IE:
void MyFunc(ref string myString) { ... }
void MyFunc(ref string myString) { ... }
the very powerful operator that is a good habit to get into is readonly ref which often has the best performance and effectively is a pointer to the variable instead of a copy of it, and it is readonly so cannot be mutated, which helps you enforce that the pointer wont be written to, only read from!
Jimmacle
Jimmacle7mo ago
that isn't his case at all, he wants to store references to value types in a list and specifically be able to mutate them which you can't do with ref
PixxelKick
PixxelKick7mo ago
ah gotcha, thats a bit trickier for sure, best option is to wrap them in a reference type for sure then to act as your "pointer" and pass the class into methods as readonly ref so the class doesnt get mutated, but its properties can be
MikeS++
MikeS++7mo ago
I did find a way to do it, basically store delegates in an array and add lambdas that set the value of the object I need it's a bit tricky but it works
Jimmacle
Jimmacle7mo ago
yeah that works, you're getting the same effect with the lambda capturing the instance of the class
PixxelKick
PixxelKick7mo ago
You actually can also just straight up use pointers in C# btw, it just has to happen inside of an unsafe { ... } block, but it works largely the same as C++
Jimmacle
Jimmacle7mo ago
which also won't work if you want to store it long-term in a list in order to get a pointer to a managed object you have to pin it so the GC can't move it, once it's unpinned you have no guarantee that data hasn't been moved
PixxelKick
PixxelKick7mo ago
based on their code at the very top however, you absolutely can do specifically that and it is, in fact, extremely similiar to the example code microsoft provides in their official example https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code
Unsafe code, pointers to data, and function pointers - C#
Learn about unsafe code, pointers, and function pointers. C# requires you to declare an unsafe context to use these features to directly manipulate memory or function pointers (unmanaged delegates).
Jimmacle
Jimmacle7mo ago
except it's not similar, it's the opposite and even in an unsafe block it's not valid to use pointer types as type arguments and they also specified that the variables are not actually locals in the same scope but members of classes