代码之家  ›  专栏  ›  技术社区  ›  Noel

C#通过引用返回结构导致复制

  •  2
  • Noel  · 技术社区  · 1 年前

    我尝试使用C#通过引用来存储和检索结构。实际发生的情况是,我试图检索的每个结构都被复制了,而ref并没有按照指示返回。

    我有一个“registry”类,它包含一组结构,我正试图通过引用访问和检索这些结构。不幸的是,这似乎没有发生,因为返回的结果似乎是数组中元素的副本。我不确定这是怎么发生的,因为调用堆栈中的每个调用都被设置为通过ref返回值。

    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);
            }
    

    组件注册器.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);
            }
    

    实体.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<雪碧>() 第二次我看到我所做的任何改变都没有被考虑在内。这告诉我必须处理一个复制的结构。

    问题是:它在哪里复制的?

    提前感谢您的建议。。。

    1 回复  |  直到 1 年前
        1
  •  5
  •   Ivan Petrov    1 年前

    复制是在方法的赋值时完成的

     var sprite = result.GetComponent<Sprite>();
    

    如果你写

    ref var sprite = ref result.GetComponent<Sprite>();
    

    它应该起作用。

    如果你很好奇为什么你可以把这两行写在一起,并使用ILSpy来查看生成的IL的差异。