Я пытался хранить и извлекать структуры по ссылке, используя C#. На самом деле произошло то, что каждая структура, которую я пытался получить, была скопирована, а не возвращена по ссылке, как указано.
У меня есть класс «реестра», который содержит массив структур, к которым я пытаюсь получить доступ и получить их по ссылке. К сожалению, похоже, этого не происходит, поскольку возвращаемый результат представляет собой копию элемента внутри массива. Я не уверен, как это происходит, поскольку каждый вызов в стеке вызовов настроен на возврат значения по ссылке.
ComponentArray.cs
public ref T GetComponentByIndex(uint idx)
{
return ref m_componentArray[idx];
}
public ref T GetComponent(uint entityId)
{
if (!m_entityToIndexMap.ContainsKey(entityId))
{
//Throwings an exception here, might be a bit much. Better to just return null.
throw new Exception("Entity does not have specified component");
}
return ref GetComponentByIndex(m_entityToIndexMap[entityId]);
}
public ref T Get(uint entityId)
{
return ref GetComponent(entityId);
}
КомпонентRegister.cs
public ref T GetComponent<T>(uint entityId)
where T : struct
{
var cmpArray = GetComponentArray<T>();
return ref cmpArray.Get(entityId);
}
EntityManager.cs
public ref T GetComponent<T>(uint entityId)
where T : struct
{
return ref m_componentRegister.GetComponent<T>(entityId);
}
Entity.cs
public ref T GetComponent<T>()
where T : struct
{
return ref m_entityManager.GetComponent<T>(m_id);
}
А вот вызывающий метод:
private GameObject CreateSpaceMarineArm(Texture2D spriteTexture)
{
var result = this.CreateGameObject("SM_Arm");
result.AddComponent<Sprite>();
var sprite = result.GetComponent<Sprite>();
sprite.Initialise(spriteTexture, new Point(0, 160), 32, 2, 0.17f);
sprite.Origin = new Vector2(0, 0);
result.Transform.Position = new Vector2(0, -4);
result.GetComponent<GameObjectData>().ShowDebugInfo = false;
return result;
}
Я вызываю .GetComponent<Sprite>(), а затем инициализирую компонент...
Однако, когда я звоню .GetComponent<Sprite>() во второй раз, я вижу, что ни одно из внесенных мной изменений не было учтено. Это говорит мне о том, что я, должно быть, имею дело с скопированной структурой.
Вопрос: Куда это скопировали?
Заранее благодарю за любой совет...
Спасибо... но ограничения устанавливаются в объявлении класса, если не в объявлении метода... Они все еще существуют.
Хороший вопрос. Правда в том, что я хотел простое хранилище значений в непрерывной памяти. Поскольку объекты размещаются в куче, я подумал, что это лучший подход.
«использовать класс. – Да». Я мог бы просто сделать это. Но мне любопытно, почему то, что я делаю, не работает.





Копирование выполняется по назначению метода
var sprite = result.GetComponent<Sprite>();
Если ты напишешь
ref var sprite = ref result.GetComponent<Sprite>();
Он должен работать.
Если вам интересно, почему вы можете написать две строки рядом друг с другом и использовать ILSpy, чтобы увидеть разницу в сгенерированных IL.
Теперь имеет смысл, что большинство этих реализаций предпочитают передавать ссылку обратно через параметр метода. Ставлю лайк .GetComponent<T>(ref T cmp) - понимаю почему....
Просто предложение, не все используют ограничение «где T: struct»? (не знаю, имеет ли это какое-то отношение?)