2011-05-02 29 views
3

我有以下代码:使用未分配的本地变量? C#

 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,但我不明白,因为在MessageBox出现每次和输出值,所以我会承担值为tt.ticketPrice正在填充ticketPrice

任何人都可以帮助我解决这个问题。

感谢

+0

我从来没有看到一个运行时错误“使用未分配的本地变量”只是一个编译时错误的排序。 – 2011-05-02 21:34:11

+1

这是一个诡计问题吗?赋值在两行之后使用'ticketPrice'的值。 – 2011-05-02 21:34:11

+3

@所有交易:呃不,它不会 - 'tt.ticketPrice'与'ticketPrice'没有关系(除了类似的名字)。 – rsenna 2011-05-02 21:42:34

回答

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#添加类似的东西。

+0

好的,我明白你,因为查询还没有完成处理,它没有时间在代码完成执行之前在ticketPrice中使用tt.ticketPrice? – 2011-05-02 21:50:56

+0

好的,我只是将计算移入事件。现在有效,但我想我必须尽量避免这种情况。谢谢(你的)信息! – 2011-05-02 21:56:13

+0

@Sandeep:是的,这正是问题所在。处理程序不能保证在main方法的执行转移到下一行之前完成(并使用'ticketPrice')。当启动一些异步操作(需要一个处理程序)时,调用方法的其余部分通常不需要包含太多的代码。 – 2011-05-02 22:11:51

1

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

0

double ticketPrive;声明移到foreach之内,一切都会好的。

+0

如果它出现在foreach中,问题出现的原因是为什么它首先出现? – BrokenGlass 2011-05-02 21:38:22

+0

它只能在lambda表达式内部使用,所以将它移动到那里! – 2011-05-02 21:40:00

+0

这是不正确的,它也可以在事件处理程序之外使用。但是,当然你必须等到事件发生。 – Guffa 2011-05-02 21:53:38

0

该变量确实被赋值,但会在稍后发生。

用于分配变量的代码位于事件处理程序中,以便在事件发生之前代码不会运行,并且在加载故障单之后。

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