Dans .NET si vous passez un struct dans une méthode avec un paramètre d'interface-t-il la valeur boîte?

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

  •  27-10-2019
  •  | 
  •  

Question

A partir d'un simple test, je peux voir que si vous passez la struct dans la méthode, il est passé par valeur, mais si vous devez d'abord l'attribuer à une interface, il est passé par référence.

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

Alors ma question est, est-il encore une opération de boxe pour faire passer une struct dans comme ça?

Était-ce utile?

La 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.

Autres conseils

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

IFoo ifoo = new Foo();

rather than when calling Bar.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top