3

I was considering using a struct to store several bits of state inside a method, however I wanted to be able to pass this to a helper method using the ref keword to avoid passing by value. If I do that however, will then be stored on the heap, rather than the stack?

example code:

var link = new Geoff("Bergen");

Perambulate(ref link);

Console.WriteLine(link.Name);

void Perambulate(ref Geoff man)
{
    Console.WriteLine("Perambulating {0}",man.Name);
}

struct Geoff
{
    public readonly string Name;

    public Geoff(string name)
    {
        Name = name;
    }
}

I guess I'm really asking if the ref keyword forces the referenced value to be stored on the heap.

Ceilingfish
  • 5,397
  • 4
  • 44
  • 71

3 Answers3

5

No it wouldn't be stored on the heap. It would just pass the reference to its location on the stack.

Also, your struct design is not good as you are allowing Name to be changed. The contents of a structure should be immutable. I'd suggest you use a class in this example.

David Arno
  • 42,717
  • 16
  • 86
  • 131
  • According to what should data of a struct be immutable? System.Int32 is a struct too and also not immutable, right? – Markus Safar Nov 01 '13 at 12:31
  • @MarkusSafar http://stackoverflow.com/questions/441309/why-are-mutable-structs-evil explains the problems with mutable structs. Int32 isn't mutable. When did you last see someone redefine 3 and being 100 for example? – David Arno Nov 01 '13 at 12:38
  • @MarkusSafar it's sometimes thought that ints are mutable because you can do `integerVariable++` however, this compiles to `integerVariable = integerVariable + 1`, which is a redefinition, not a modification. – Ceilingfish Nov 01 '13 at 13:43
  • 1
    @Ceilingfish The confusion seems to arise over understanding that structs are values and that values shown be immutable, but there is no requirement (or even ability in C# sadly) to declare a variable must be immutable. – David Arno Nov 01 '13 at 13:47
  • Thanks for the link, seems I never (until now) thought and researched that topic deep enough. But your points seem (at least now) absolutly logical to mee ;-) – Markus Safar Nov 01 '13 at 14:26
  • @Ceilingfish `i=i+1` is not a redefinition. – CITBL Nov 01 '13 at 15:49
  • @CITBL That was the point Ceilingfish was making. People can confuse reassignment and redefinition. – David Arno Nov 01 '13 at 15:54
2

What you are referring to is called boxing and no, boxing doesn't occur when passing a value type by reference. It'll just pass the reference to Geoff on the stack.

Boxing can happen when casting a value type to a reference type (implicitly as well as explicitly). E.g.:

var g = new Geoff(); //value type
List<object> objects = new List<object>(); //collection of objects (reference type)
objects.Add(g); //implicitly casting g to object

This will cause the Geoff instance to be copied to the heap, which is called boxing.

Now if your Perambulate method accepted an object as a parameter, your passed Geoff would be boxed and copied to the heap.

Fayilt
  • 1,042
  • 7
  • 16
0

No it wouldn't. Your struct is already on the stack. It won't be moved to the heap just because you've passed its reference to some method.
Your Perambulate method just receives a references (i.e. an address) to your struct which is stored on the stack.

CITBL
  • 1,587
  • 3
  • 21
  • 36