C# structs are allocated on the stack unless "boxed". when "boxed" they are copied to the heap and must be garbage collected like a class instance. also as they do not implement inheritance, the methods do not require a vtable.
the C# default is pass by value. to pass by ref, you use the ref key word
using System;
int i = 0;
callbyvalue(i);
Console.WriteLine(i); // 0
callbyref(ref i);
Console.WriteLine(i); // 2
void callbyvalue(int x)
{
x = 1;
}
void callbyref(ref int x)
{
x = 2;
}