2

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

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

所以我的问题是,仍然有一个拳击操作来传递这样的结构吗?

4

2 回答 2

7

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

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 
{
}

这使用了泛型对每种值类型都专门化的事实。


但是,如果您遵循可变结构是邪恶的设计准则,从而使您的结构不可变,那么代码框是否无关紧要。然后,拳击只会对性能造成轻微影响,但不会对语义产生太大影响。

于 2011-03-19T17:28:11.633 回答
1

接口都是引用类型,所以装箱就行了

IFoo ifoo = new Foo();

而不是打电话时Bar

于 2011-03-19T17:28:31.180 回答