If a class or struct-type variable exposes a value-type field, and that value type exposes its contents as fields, operations on those fields can be performed as efficiently as operands on the surrounding variable type. IF the value type is exposed as a property, then the best one can do is generally something like:
var temp = t.Location;
temp.X += 4;
t.Location = temp;
Not terribly elegant, but relatively clear and not too horribly inefficient. An alternative would be to have the tank expose a method AdjustLocation
, something like:
delegate void ActByRef<T1>(ref T1 p1);
void ActOnLocation(ActByRef<Point> proc)
{ proc(ref _Location); }
and probably also
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); }
These methods assume that the Location
property uses a backing field named _Location
. Code could then do something like:
// Add 5 to X
myTank.ActOnLocation( (ref Point loc) => loc.X += 5 );
or
// Add YSpeed to Y
myTank.ActOnLocation( (ref Point loc, ref int param) => loc.Y += param, ref YSpeed);
Note that in the latter case, neither YSpeed
, nor this
, nor any other local variable, is not used within the lambda; instead, YSpeed
is passed as a ref
parameter. Because of that, even if the above code is run a million times, the system will only have to generate one delegate which can then be re-used every time.
If the structure were large, the above approach could be faster than the approach using a temporary variable. While overhead is probably greater than the cost of copying a small structure, the overhead is independent of structure size. One could efficiently use structures that were several kilobytes in size if one used constructs like the above so as to avoid having to make temporary copies.