Wenn eine Klasse oder Struktur-Typ Variable ein Wert-Typ-Feld aussetzt, und dieser Wert Typ macht seinen Inhalt als Felder, Operationen auf diesen Feldern können so effizient wie Operanden auf dem umgebenden Variablentyp durchgeführt werden.Wenn der Wert Typ als Eigenschaft ausgesetzt ist, dann tun das Beste, was man in der Regel so etwas wie:
var temp = t.Location;
temp.X += 4;
t.Location = temp;
Nicht besonders elegant, aber relativ klar und nicht zu schrecklich ineffizient. Eine Alternative wäre der Tank wie ein Verfahren AdjustLocation
, etwas aussetzen zu haben:
delegate void ActByRef<T1>(ref T1 p1);
void ActOnLocation(ActByRef<Point> proc)
{ proc(ref _Location); }
und wahrscheinlich auch
delegate void ActByRef<T1,T2>(ref T1 p1, ref T2 p2);
void ActOnLocation<PT1>(ActByRef<Point, PT1>, ref PT1 param1)
{ proc(ref _Location, ref param1); }
Diese Methoden gehen davon aus, dass die Location
Eigenschaft ein Trägerfeld _Location
namens verwendet. Code könnte dann so etwas wie:
// Add 5 to X
myTank.ActOnLocation((ref Point loc) => loc.X += 5);
oder
// Add YSpeed to Y
myTank.ActOnLocation((ref Point loc, ref int param) => loc.Y += param, ref YSpeed);
Beachten Sie, dass im letzteren Fall, weder YSpeed
noch this
, noch irgendeine andere lokale Variable, nicht innerhalb der Lambda verwendet wird; Stattdessen wird YSpeed
als ref
Parameter übergeben. Aus diesem Grund muss das System, selbst wenn der obige Code millionenfach ausgeführt wird, nur einen Delegierten generieren, der dann jedes Mal wiederverwendet werden kann.
Wenn die Struktur groß wäre, könnte der obige Ansatz schneller sein als der Ansatz mit einer temporären Variablen. Während der Overhead wahrscheinlich größer ist als die Kosten für das Kopieren einer kleinen Struktur, ist der Overhead unabhängig von der Strukturgröße. Man könnte effizient Strukturen verwenden, die mehrere Kilobyte groß sind, wenn man Konstrukte wie die obigen verwendet, um zu vermeiden, dass man temporäre Kopien machen muss.
Ich würde vorschlagen, Tank.Offset (int x, int y) 'als Alternative und halten Sie Ihr Rechteck privat. Ihr Offset-Code würde den Standort des Tanks ändern. – FlyingStreudel
Bewegung scheint etwas zu sein, das du am Tank ausführst, daher eine Methode. Anstatt die relative Position zu ändern, indem Sie direkt eine Eigenschaft/ein Feld manipulieren. – Marc
Ich stimme den obigen beiden Kommentaren zu. Aber wenn Sie _really_ wollten, um es zu umgehen, ohne Methoden zu verwenden, _ _ sollten _ separate _ X'- und 'Y'-Eigenschaften erstellen, die nur um das untergeordnete' Location'-Rechteck herum kartografieren, also würden Sie 'myTank.X + = 10' haben. –