2

From a simple test I can see that if you pass the struct into the method it is passed by value but if you first assign it to an interface it is passed by reference.

interface IFoo { int Val { get; set; } }
struct Foo : IFoo { public int Val { get; set; } }

void Bar(IFoo foo) { foo.Val = 1; }

Foo foo = new Foo();
IFoo ifoo = new Foo();

Bar(foo);
Bar(ifoo);

Console.WriteLine(foo.Val);  // 0, passed by value
Console.WriteLine(ifoo.Val); // 1, passed by ref

So my question is, is there still a boxing operation for passing a struct in like this?

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
justin.m.chase
  • 13,061
  • 8
  • 52
  • 100

2 Answers2

9

Whenever a struct gets converted to an interface it gets boxed.

Foo foo = new Foo();//Doesn't box yet
IFoo ifoo = new Foo();//Boxes

Bar(foo);//creates a new boxed copy
Bar(ifoo);//Uses the old boxed version created in line 2

You can avoid that boxing by making the parameter generic using the interface as a constraint:

void Bar<T>(T foo)
    where T:IFoo 
{
}

This uses the fact that generics get specialized for every value type.


But if you follow the design guideline that mutable strucs are evil, and thus make your struct immutable, it doesn't matter much if the code boxes or not. The boxing then only causes a slight performance hit, but doesn't change semantics much.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
1

Interfaces are all reference types, so the boxing occurs on the line

IFoo ifoo = new Foo();

rather than when calling Bar.

Lee
  • 142,018
  • 20
  • 234
  • 287
  • Right, that case is clear. But what about the other case? Where you're passing foo into the method and it's passed by value rather than by reference into Bar. Will boxing still occur? – justin.m.chase Mar 19 '11 at 17:56
  • 1
    @Justin - Yes, when `Bar(foo)` is called, a boxed copy of `foo` is created which is passed into `Bar`, which is why the change is not reflected in the calling method. In the case of `ifoo` you are just passing a reference to the boxed copy, so the change is visible. – Lee Mar 19 '11 at 18:03