3

我有以下代码:

        double ticketPrice;
        LoadOperation loGetTickets = ticketClass.loadTickets();
        loGetTickets.Completed += (s, args) =>
        {
            foreach (Web.Ticket tt in ticketClass.getContext())
            {
                if (tt.bookingId == data.bookingId)
                {
                    pView.lblTicketAmount.Content = "£" + tt.ticketPrice;
                    MessageBox.Show("Price: " + tt.ticketPrice);
                    ticketPrice = Convert.ToDouble(tt.ticketPrice);
                    pView.lblTicketName.Content = tt.ticketName;
                    break;
                }
            }
        }; double subTotal = ticketPrice + ticketQuantity;

当我运行它时,我收到错误:使用未分配的局部变量'ticketPrice'

如您所见,它确实从循环中分配了一个值。

如果我确实使用:

double ticketPrice = 0.0;

错误发生,但值保持在0.0,但我不明白,因为消息框每次都会出现并输出值,所以我假设 的值tt.ticketPrice正在填充ticketPrice

任何人都可以在这件事上帮助我。

谢谢

4

4 回答 4

3

您是说 的值ticketPrice保持为零,但代码没有显示您读取变量值的位置!

如果在您发布的代码段之后的某些代码中使用了该行为,则该行为将是有意义的。例如:

double ticketPrice;        
LoadOperation loGetTickets = ticketClass.loadTickets();        
loGetTickets.Completed += (s, args) =>  { 
  // Set value of 'ticketPrice'
  ticketPrice = ...
};

// Use the value of the variable
Console.WriteLine(ticketPrice); // (*)

这不起作用,因为标记为(*)实际完成的行在处理程序中设置变量的值之前Completed完成。要使其工作,您需要将使用变量的代码移动到处理程序中(在设置变量值的代码之后)。

然后,当然,在方法中声明变量是没有意义的,因为它只会在 lambda 函数的主体中使用,所以你最终会得到这样的结果:

LoadOperation loGetTickets = ticketClass.loadTickets();        
loGetTickets.Completed += (s, args) =>  { 
  double ticketPrice;        
  // Set value of 'ticketPrice'
  ticketPrice = ...

  // Use the value of the variable
  Console.WriteLine(ticketPrice); // (*)
};

我相信您刚刚发现了 C# 4 中异步编程的痛点 :-)。这就是为什么 F# 支持异步工作流(您可以在其中编写相同的代码而无需事件处理程序)以及为什么 C# 设计人员正在考虑在未来向 C# 添加类似的东西。

于 2011-05-02T21:39:43.840 回答
1

虽然ticketPrice确实在循环中设置,但它位于事件处理程序中。由于该事件有可能永远不会触发(就编译器而言),它会将其视为未分配,直到遇到保证运行的行。

于 2011-05-02T21:35:43.100 回答
0

变量确实被分配了,但这会在以后发生。

分配变量的代码位于事件处理程序中,因此该代码在事件发生之前不会运行,也就是在加载票证之后。

如果您尝试立即使用该变量,它将不会被设置。在事件发生之前,您不能使用该变量。最简单的方法是将使用该变量的代码放入事件处理程序中。

于 2011-05-02T21:50:15.320 回答
0

double ticketPrive;语句移到内部foreach,一切都会好起来的。

于 2011-05-02T21:35:52.663 回答