当代码从 keydown 事件移动到函数中时,c# 变量会重置 - 谁能解释为什么?
c# variables reset when code is moved from keydown event into a function - can anyone explain why?
我在 VS Express 2010 中使用 C# windows 表单应用程序。我正在使用一些代码来进行学习。我有一个表单对象,我想通过按键不断地向一个方向移动 - 原始代码可以正常工作。
在尝试通过将 "movement" 的代码移动到函数中来整理它的过程中,代码不再像以前那样工作。现在,我的对象不再沿所选方向从其当前位置移动,而是在每次按下键时重置其位置。我想知道为什么会这样,因为我所做的更改绝对是最小的。请看代码:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
direction = 4;
}
if (e.KeyCode == Keys.Up)
{
direction = 2;
}
if (e.KeyCode == Keys.Right)
{
direction = 3;
}
if (e.KeyCode == Keys.Left)
{
direction = 1;
}
while (direction != 0)
{
Application.DoEvents();
if (direction == 1)
{
X = X - 1;
}
else if (direction == 2)//up
{
Y = Y - 1;
}
else if (direction == 3)
{
X = X + 1;
}
else if (direction == 4)//down
{
Y = Y + 1;
}
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
当我将 while 循环移动到移动函数中时,变量 X 和 Y 在每次按键时都重置为 0。此代码如下所示:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
direction = 4;
}
if (e.KeyCode == Keys.Up)
{
direction = 2;
}
if (e.KeyCode == Keys.Right)
{
direction = 3;
}
if (e.KeyCode == Keys.Left)
{
direction = 1;
}
movement(X, Y, direction);
}
我觉得我在这里遗漏了一些明显的东西,但我不明白为什么它的行为有所不同。感谢您的帮助:)
编辑 1:移动函数的代码:
movement(int X, int Y, int direction)
{
while (direction != 0)
{
Application.DoEvents();
if (direction == 1)
{
X = X - 1;
}
else if (direction == 2)//up
{
Y = Y - 1;
}
else if (direction == 3)
{
X = X + 1;
}
else if (direction == 4)//down
{
Y = Y + 1;
}
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
我想您的 movement
方法更改了作为参数提供的 X
和 Y
。但是,参数X
和Y
传递的是'by value',而不是'by reference'。
如果你想让这个工作,你要么必须使用 class 变量,并删除方法调用中的参数,要么使用 ref
,我将演示:
movement(ref X, ref Y, direction);
并且:
private void movement(ref int X, ref int Y, int direction)
{ }
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down) direction = 4;
else if (e.KeyCode == Keys.Up) direction = 2;
else if (e.KeyCode == Keys.Right) direction = 3;
else if (e.KeyCode == Keys.Left) direction = 1;
while (direction != 0)
{
Application.DoEvents();
if (direction == 1) X--;
else if (direction == 2) Y--;
else if (direction == 3) X++;
else if (direction == 4) Y++;
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
可以改写:
private void SetDirection(KeyEventArgs e)
{
if (e.KeyCode == Keys.Down) direction = 4;
else if (e.KeyCode == Keys.Up) direction = 2;
else if (e.KeyCode == Keys.Right) direction = 3;
else if (e.KeyCode == Keys.Left) direction = 1;
}
private void ApplyMovement()
{
while (direction != 0)
{
Application.DoEvents();
if (direction == 1) X--;
else if (direction == 2) Y--;
else if (direction == 3) X++;
else if (direction == 4) Y++;
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
SetDirection(e);
ApplyMovement();
}
您必须了解变量 X
、Y
和 direction
是 class 成员,因此可以从 [=39= 中的任何位置访问它们],并且当您调用 movement(X, Y, direction)
时,movement
将使用这些变量的 副本 ,因此当您在 movement
中执行 X = X + 1
方法,您实际上并没有更改 class 的 X
值,而只是更改了它的 copy。
这意味着变量 X 和 Y(即 class 成员)不会在每次按键时 重置 为 0。事实上 它们永远不会设置为任何其他值.
请注意,您也可以使用 switch
语句代替所有那些 if
s。
switch (direction)
{
case 1: X--; break; // left
case 2: Y--; break; // up
case 3: X++; break; // right
case 4: Y++; break; // down
}
我在 VS Express 2010 中使用 C# windows 表单应用程序。我正在使用一些代码来进行学习。我有一个表单对象,我想通过按键不断地向一个方向移动 - 原始代码可以正常工作。
在尝试通过将 "movement" 的代码移动到函数中来整理它的过程中,代码不再像以前那样工作。现在,我的对象不再沿所选方向从其当前位置移动,而是在每次按下键时重置其位置。我想知道为什么会这样,因为我所做的更改绝对是最小的。请看代码:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
direction = 4;
}
if (e.KeyCode == Keys.Up)
{
direction = 2;
}
if (e.KeyCode == Keys.Right)
{
direction = 3;
}
if (e.KeyCode == Keys.Left)
{
direction = 1;
}
while (direction != 0)
{
Application.DoEvents();
if (direction == 1)
{
X = X - 1;
}
else if (direction == 2)//up
{
Y = Y - 1;
}
else if (direction == 3)
{
X = X + 1;
}
else if (direction == 4)//down
{
Y = Y + 1;
}
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
当我将 while 循环移动到移动函数中时,变量 X 和 Y 在每次按键时都重置为 0。此代码如下所示:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
direction = 4;
}
if (e.KeyCode == Keys.Up)
{
direction = 2;
}
if (e.KeyCode == Keys.Right)
{
direction = 3;
}
if (e.KeyCode == Keys.Left)
{
direction = 1;
}
movement(X, Y, direction);
}
我觉得我在这里遗漏了一些明显的东西,但我不明白为什么它的行为有所不同。感谢您的帮助:)
编辑 1:移动函数的代码:
movement(int X, int Y, int direction)
{
while (direction != 0)
{
Application.DoEvents();
if (direction == 1)
{
X = X - 1;
}
else if (direction == 2)//up
{
Y = Y - 1;
}
else if (direction == 3)
{
X = X + 1;
}
else if (direction == 4)//down
{
Y = Y + 1;
}
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
我想您的 movement
方法更改了作为参数提供的 X
和 Y
。但是,参数X
和Y
传递的是'by value',而不是'by reference'。
如果你想让这个工作,你要么必须使用 class 变量,并删除方法调用中的参数,要么使用 ref
,我将演示:
movement(ref X, ref Y, direction);
并且:
private void movement(ref int X, ref int Y, int direction)
{ }
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down) direction = 4;
else if (e.KeyCode == Keys.Up) direction = 2;
else if (e.KeyCode == Keys.Right) direction = 3;
else if (e.KeyCode == Keys.Left) direction = 1;
while (direction != 0)
{
Application.DoEvents();
if (direction == 1) X--;
else if (direction == 2) Y--;
else if (direction == 3) X++;
else if (direction == 4) Y++;
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
可以改写:
private void SetDirection(KeyEventArgs e)
{
if (e.KeyCode == Keys.Down) direction = 4;
else if (e.KeyCode == Keys.Up) direction = 2;
else if (e.KeyCode == Keys.Right) direction = 3;
else if (e.KeyCode == Keys.Left) direction = 1;
}
private void ApplyMovement()
{
while (direction != 0)
{
Application.DoEvents();
if (direction == 1) X--;
else if (direction == 2) Y--;
else if (direction == 3) X++;
else if (direction == 4) Y++;
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
SetDirection(e);
ApplyMovement();
}
您必须了解变量 X
、Y
和 direction
是 class 成员,因此可以从 [=39= 中的任何位置访问它们],并且当您调用 movement(X, Y, direction)
时,movement
将使用这些变量的 副本 ,因此当您在 movement
中执行 X = X + 1
方法,您实际上并没有更改 class 的 X
值,而只是更改了它的 copy。
这意味着变量 X 和 Y(即 class 成员)不会在每次按键时 重置 为 0。事实上 它们永远不会设置为任何其他值.
请注意,您也可以使用 switch
语句代替所有那些 if
s。
switch (direction)
{
case 1: X--; break; // left
case 2: Y--; break; // up
case 3: X++; break; // right
case 4: Y++; break; // down
}