Прежде всего, существует тот факт, что спецификация явно заявляет, что они являются объектами во многих местах, включая здесь , где он определяет термин «функция»:
function
член типа Object, который может быть вызван как подпрограмма
blockquote>Эмпирически существует множество способов доказать это, но один из Проще всего назначить значение для него свойства:
var foo = function() { }; foo.myProperty = "my value"; console.log(foo.myProperty); // "my value"
Или использовать один в качестве прототипа (что необычно, но возможно) , что доказывает его, что только объекты могут быть прототипами:
var foo = function() { }; var obj = Object.create(foo); console.log(Object.getPrototypeOf(obj) === foo); // true
Индексатор вернет копию значения. Внесение изменений в эту копию ничего не сделает со значением в словаре ... компилятор останавливает вас от написания багги-кода. Если вы хотите изменить значение в словаре, вам нужно будет использовать что-то вроде:
// Note: copying the contents to start with as you can't modify a collection
// while iterating over it
foreach (KeyValuePair<string, MapTile> pair in tilesData.ToList())
{
MapTile tile = pair.Value;
tile.bgFrame = tile.bgFrame >= tile.bgAnimation ? 0 : tile.bgFrame + 1;
tilesData[pair.Key] = tile;
}
Обратите внимание, что это также , избегая выполнения нескольких поисков без пользы Причина, по которой выполнялся ваш оригинальный код.
Лично я настоятельно рекомендую против иметь сменяемую структуру, чтобы начать с вас ...
Конечно, другой альтернативой является создание ссылочного типа, с которого вы могли бы использовать:
// If MapTile is a reference type...
// No need to copy anything this time; we're not changing the value in the
// dictionary, which is just a reference. Also, we don't care about the
// key this time.
foreach (MapTile tile in tilesData.Values)
{
tile.bgFrame = tile.bgFrame >= tile.bgAnimation ? 0 : tile.bgFrame + 1;
}
Chance struct to Class
до:
public struct MapTile
{
public int bgAnimation;
public int bgFrame;
}
после:
public Class MapTile
{
public int bgAnimation;
public int bgFrame;
}
tilesData[tile.Key]
не является местом хранения (т. е. это не переменная). Это копия экземпляра MapTile
, связанная с ключом tile.Key
в словаре tilesData
. Это то, что происходит с struct
.
Что вам нужно сделать, это:
MapTile tile = tilesData[tile.Key];
if (tile.bgFrame >= tile.bgAnimation)
{
tile.bgFrame = 0;
}
else
{
tile.bgFrame++;
}
tilesData[tile.Key] = tile;
struct
- типы значений. Характерными особенностями типов значений являются то, что они копируются по значению, а равенство определяется равенством ценности.
– jason
6 June 2011 в 18:12
Я бы предложил создать класс утилиты:
public class MutableHolder<T>
{
public T Value;
public MutableHolder(T value)
{
this.Value = value;
}
}
Затем сохраните вновь созданный MutableHolder<MapTile>
в каждом слоте словаря, а не сразу сохраните MapTile
. Это позволит вам легко обновить фрагмент карты, связанный с каким-либо конкретным ключом, без необходимости изменять сам словарь (действие, которое в противном случае, как минимум, аннулирует счетчик, используемый вашим циклом foreach
).