In .NET if you pass a struct into a method with an interface parameter does it box the value?

StackOverflow https://stackoverflow.com/questions/5363587

  •  27-10-2019
  •  | 
  •  

Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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

IFoo ifoo = new Foo();

rather than when calling Bar.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top