En .NET Si pasa una estructura a un método con un parámetro de interfaz, ¿encerra el valor?

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

  •  27-10-2019
  •  | 
  •  

Pregunta

Desde una prueba simple, puedo ver que si pasa la estructura al método, se pasa por valor, pero si primero lo asigna a una interfaz, se pasa por referencia.

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

Entonces, mi pregunta es, ¿todavía hay una operación de boxeo para pasar una estructura como esta?

¿Fue útil?

Solución

Cada vez que una estructura se convierte en una interfaz, se encaja.

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

Puede evitar ese boxeo haciendo el parámetro genérico utilizando la interfaz como una restricción:

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

Esto utiliza el hecho de que los genéricos se especializan para cada tipo de valor.


Pero si sigue la directriz de diseño de que las estructuras mutables son malvadas y, por lo tanto, hacen que su estructura sea inmutable, no importa mucho si el código se cuadra o no. El boxeo solo causa un ligero golpe de rendimiento, pero no cambia mucho la semántica.

Otros consejos

Las interfaces son todos los tipos de referencia, por lo que el boxeo ocurre en la línea

IFoo ifoo = new Foo();

en lugar de cuando llame Bar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top