在.NET中,如果将结构传递给带有接口参数的方法,它会将值设置为空吗?

jus*_*ase 1 c# boxing byref byval

从一个简单的测试我可以看到,如果你将结构传递给方法,它将通过值传递,但如果你首先将它分配给一个接口,它将通过引用传递.

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
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,是否还有像这样传递结构的装箱操作?

Cod*_*aos 5

每当结构转换为接口时,它就会被装箱.

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
Run Code Online (Sandbox Code Playgroud)

您可以通过使用接口作为约束使参数通用来避免该装箱:

void Bar<T>(T foo)
    where T:IFoo 
{
}
Run Code Online (Sandbox Code Playgroud)

这使用了泛型专门针对每种值类型的事实.


但是如果你遵循设计准则,可变的结构是邪恶的,从而使你的结构不可变,那么如果代码框没有那么重要.拳击然后只会导致轻微的性能打击,但不会更改语义.