在Monogame中,为什么Rectangle.Offset不起作用?

我有一个默认的Monogame游戏项目中的以下代码:

protected override void Update(GameTime gameTime) { if (Keyboard.GetState().IsKeyDown(Keys.Left)) { paddle.Box.Offset(-10, 0); Debug.WriteLine(paddle.Box); } if (Keyboard.GetState().IsKeyDown(Keys.Right)) { paddle.Box.Offset(10, 0); Debug.WriteLine(paddle.Box); } base.Update(gameTime); } 

paddle.Box是一个正常的XNA Rectangle。

问题是调用任何Offset()重载之后, paddle.Box的位置不会改变,因为debugging确认。 如果我只是分配一个新的矩形,它的工作,但Offset (和Inflate() ,FWIW)似乎被打破。

我究竟做错了什么?

这是因为Rectangle是一个结构,这使得这是一个棘手的情况。 由于C#中的值被传递并返回,所以调用Paddle.Box将返回一个Paddle.Box的副本 。 之后,你可以在这个Paddle.Box的新副本上调用Offset,但是它是副本,而不是你想要改变的矩形! 然而,副本确实发生了变化,但在该行之后直接丢弃。 这就是为什么调用'= new Rectangle …'的原因。

你会遇到类似的东西与内置向量ntypes。分配一个新的对象('… =新…')通常是你应该在这些情况下做的。 (注意,我相信C#甚至会阻止你在属性和成员variables上这样做)。

编辑:一个更实际的答案:如果你想使用偏移,你可以做这样的事情,而不是:

 protected override void Update(GameTime gameTime) { if (Keyboard.GetState().IsKeyDown(Keys.Left)) { Rectangle box = paddle.Box; box.Offset(-10, 0); paddle.Box = box; Debug.WriteLine(paddle.Box); } if (Keyboard.GetState().IsKeyDown(Keys.Right)) { Rectangle box = paddle.Box; box.Offset(10, 0); paddle.Box = box; Debug.WriteLine(paddle.Box); } base.Update(gameTime); }