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
  •  | 
  •  

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?

有帮助吗?

解决方案

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.

其他提示

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

IFoo ifoo = new Foo();

rather than when calling Bar.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top