Всякий раз, когда структура преобразуется в интерфейс, она упаковывается.
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
Этого бокса можно избежать, сделав параметр универсальным, используя интерфейс в качестве ограничения:
void Bar<T>(T foo)
where T:IFoo
{
}
При этом используется тот факт, что дженерики становятся специализированными для каждого типа значения.
Но если вы следуете руководству по проектированию, что изменяемые структуры являются злом и, таким образом, делают вашу структуру неизменной, это не имеет большого значения, есликодовые поля или нет.В этом случае бокс вызывает лишь незначительное снижение производительности, но не сильно меняет семантику.