Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding reference to structures into C# lists

Tags:

c#

Trying to keep my C# code optimized, I found that if I have a list of structure elements, each insertion would be a full copy - something that I would like to avoid.

In C++ I would simply keep a list of pointers and so I was wondering if I can do the same using C#, maybe by having the list as a list of references to the structure. Unfortunately the structure cannot be turned into a class as it is part of the XNA library (Vector3, Matrix, etc...) In any case - how would the format and usage look like if it's possible?

Thanks.

like image 632
Adi Avatar asked Dec 08 '11 16:12

Adi


2 Answers

No, basically. Options:

  • use a class (you've already said you can't)
  • box it
  • write a class that wraps it (essentially, manual boxing)
  • use an array, and access it only directly in the array by index (without copying into a variable); this is then talking directly to the item in the array (no copy)

As an example of the last;

if(arr[idx].X == 20) SomeMethod(ref arr[idx]);

Both the .X, and any usage within SomeMethod, are accessing the value directly in the array, not a copy. This is only possible with vectors (arrays), not lists.

One reason a list of refs to structs isn't possible: it would allow you I store, in the list, the address of a variable on the stack; the array usually outlives the variable on the stack, so that would be ludicrously unsafe

like image 145
Marc Gravell Avatar answered Oct 19 '22 02:10

Marc Gravell


You can't create storeable references to structures in C#, but you could create a reference type wrapper for your value type. That said, the overhead associated with copying the memory is not going to be high for a small structure. Has your profiling shown that this is a problem?


Below is an example of a value type wrapped in a reference type. Note that this only works if all access to a particular value is through the wrapping reference type. This violates standard rules of insulation (because of the public field), but this is a bit of a special case.

public sealed class Reference<T>
    where T: struct
{
    public T Value;

    public Reference(T value)
    {
        Value = value;
    }
}

Another thing worth noting is that the Reference wrapper itself can take on the value null, though its contents are non-nullable. You can also add implicit or explicit conversion operators to make this more transparent, if you wish.

like image 5
Dan Bryant Avatar answered Oct 19 '22 02:10

Dan Bryant