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 に答える