In .NET, wenn Sie eine Struktur in eine Methode mit einem Schnittstellenparameter übergeben, fasst sie den Wert?

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

  •  27-10-2019
  •  | 
  •  

Frage

Aus einem einfachen Test kann ich sehen, dass sie, wenn Sie die Struktur in die Methode übergeben, von Wert übergeben wird. Wenn Sie sie jedoch zuerst einer Schnittstelle zuweisen, wird sie mit Referenz übergeben.

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

Meine Frage ist also, gibt es immer noch einen Boxvorgang, um eine Struktur wie diese zu übergeben?

War es hilfreich?

Lösung

Immer wenn eine Struktur in eine Schnittstelle umgewandelt wird, wird sie gebeugt.

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

Sie können dieses Boxen vermeiden, indem Sie den Parameter generisch mithilfe der Schnittstelle als Einschränkung generieren:

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

Dies verwendet die Tatsache, dass Generika für jeden Werttyp spezialisiert werden.


Wenn Sie jedoch der Entwurfsrichtlinie befolgen, dass veränderliche Strucs böse sind und Ihre Struktur so unveränderlich machen, spielt es keine Rolle, ob die Codeboxen oder nicht. Das Boxen verursacht dann nur einen leichten Leistungsverlust, ändert sich aber nicht sehr die Semantik.

Andere Tipps

Schnittstellen sind alle Referenztypen, daher erfolgt das Boxing in der Zeile

IFoo ifoo = new Foo();

eher als wenn man anruft Bar.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top