Некоторые люди предлагают использовать тип класса для хранения значений X и Y. Я с подозрением отношусь к такому подходу и предположил бы, что во многих случаях семантика, полученная путем представления player
как поля, была бы намного чище (хотя мне неясно, почему map
имеет член с именем player
. Если map
является ссылкой на MapType
, а экземпляр MapType
имеет поле типа структуры player
, с полем x
типа integer, ясно, что изменение map.player.x
повлияет на один экземпляр MapType
. Также, сказав map1.player = map2.player;
, вы скопируете поля из map2.player
в map1.player
. В отличие от этого, если бы player
относился к типу класса, а один имел map1.player = map2.player; map1.player.x = 5;
, это бы затронуло и map1
, и map2
.
Вопрос о том, следует ли использовать изменяемую структуру по сравнению с изменяемым классом, довольно прост, но понятие «если оно изменчиво, сделайте его классом» просто неверно. Просто спросите себя, учитывая:
thing1 = thing2;
thing1.x = 5;
хотите, чтобы второе утверждение влияло на значение thing2.x
? Если да, используйте класс. Если нет, используйте структуру.
Кстати, еще один шаблон, который следует учитывать, если вы не хотите, чтобы ваш тип карты отображал player
, так как это поле будет означать, что оно представляет метод ActOnPlayer:
public delegate ActionByRef<T>(ref T p);
public delegate ActionByRef<T1,T2>(ref T1 p1, ref T2 p2);
public void ActOnPlayer(ActionByRef<playerType> proc;)
{
proc(ref _player);
}
public void ActOnPlayer<T>(ActionByRef<playerType,T> proc, ref T param;)
{
proc(ref _player, ref param);
}
... sample usage:
map.ActOnPlayer((ref playerType it, ref int theParam) ->
{it.x = theParam;}, someIntVariable);
Обратите внимание, что последний подход будет выглядеть как использование замыкания, но в отличие от использования замыкания он не будет генерировать какие-либо новые объекты временной кучи и, следовательно, не будет создавать никакого давления на сборщик мусора.