2011-12-21 28 views
5

có mã này, tôi không hiểu tại sao nếu gán một biến trong khối cuối cùng thì không hiểu nó sẽ luôn được chỉ định. Tôi nghĩ rằng tôi thiếu một tùy chọn hợp lệ mà tiền tệ sẽ không được chỉ định. Nếu bạn biết, sẽ rất tuyệt vời để hiểu tại sao. nhiều đánh giá cao nó!Sử dụng biến cục bộ chưa được chỉ định. Nhưng luôn rơi vào nhiệm vụ

Cảm ơn!

CurrencyVO currency; 

try 
{ 
    if (idConnection.HasValue && idConnection != 0) 
    { 
     currencyConnection = client.GetConnection(idConnection.Value); 
     model.Connection = currencyConnection; 
    } 
    else 
    { 
     int providerUserKey = (int)Models.UserModel.GetUser().ProviderUserKey; 
     currencyConnection = client.GetConnection(providerUserKey); 
    }       
    currency = model.Currencies.SingleOrDefault(c => c.IdCountry == currencyConnection.idcountry) ?? new CurrencyVO();  
} 
catch 
{ 
     currency = new CurrencyVO();      
} 
finally 
{ 
     model.PublishedContainer.Currency = currency; 
} 

lỗi xảy ra trên khối cuối cùng. Nếu tôi lấy nó ra khỏi khối cuối cùng như thế này:

nó hoạt động tốt.

+1

Yoy nên nêu bài đăng này là câu hỏi – jclozano

+0

Thay thế dòng cuối cùng của khối Thử bằng "currency = new CurrencyVO();" làm cho nó không lỗi, phải không? – UnhandledExcepSean

+0

@SpectralGhost: không có gì bên trong khối 'try' sẽ thay đổi lỗi -' tiền tệ' cần được gán trước khối 'try' (ngay cả khi chỉ định' null'). –

Trả lời

8

Việc phân định theo dõi rằng C# biên dịch thực hiện doesn' t nhất thiết phải thực hiện một phân tích hoàn chỉnh (điều đó sẽ không thể xảy ra trong trường hợp chung) - có những quy tắc hạn chế sự phức tạp của một phân tích ler sẽ thực hiện. Nguyên tắc bao gồm các khối finally đây là tài liệu tại http://msdn.microsoft.com/en-us/library/aa691181.aspx:

Đối với một câu lệnh try stmt dạng:

trythử khốifinallycuối cùng-block

  • Trạng thái chuyển nhượng xác định v vào đầu try-block giống với trạng thái chuyển nhượng nhất định của v tại số đầu số stmt.
  • Các định nhà nước giao v vào đầu cuối cùng-block cũng giống như tình trạng phân công rõ ràng của v tại đầu stmt.
  • ...

Vì vậy, ví dụ cụ thể của bạn, vì currency không chắc chắn được gán vào đầu của khối try, nó được coi là không chắc chắn được gán vào đầu của khối finally.

+1

Bạn đánh bại tôi trong khi tôi đang thử nghiệm mã :) Trong ví dụ trên, nếu hàm tạo cho CurrencyVO ném một ngoại lệ, thực thi sẽ nhấn khối cuối cùng với tiền tệ vẫn chưa được xác định. – TheEvilPenguin

0

Bạn đang tạo đối tượng CurrencyVO mới bên trong khối catch: sẽ chỉ thực thi nếu có lỗi/ngoại lệ. Do đó, nếu bạn không gặp ngoại lệ: biến số currency sẽ không được chỉ định. Đó là lý do tại sao bạn không thể sử dụng nó.

chỉnh sửa: làm cho những thay đổi sau cho mã của bạn để biên dịch:

CurrencyVO currency = null; 

và cuối cùng:

if (currency != null) 
    model.PublishedContainer.Currency = currency; 

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/a994a0ff-432b-4d23-b7d2-838b0b961de0

+0

Tiền tệ được gán vào dòng cuối cùng của thử – Joe

+0

@Joe: true, tôi nhận thấy rằng sau này nhưng tôi đoán rằng trình biên dịch không thể đảm bảo rằng nhiệm vụ đó sẽ được thực hiện và đó là lý do tại sao nó không cho phép sử dụng biến – olegvs

+0

Thật sao? Có vẻ như nó sẽ được chỉ định trong thử hoặc bắt. Người ta phải bị bắt, phải không? – Joe

1

Điều gì sẽ xảy ra nếu new CurrencyVO() gây ra ngoại lệ trong khối catch? A-ha!

+0

đẹp. Tôi để lại sự chấp nhận cho câu trả lời chính thức hơn nhưng câu trả lời này là 'thông minh'. +1 –

1

Bạn có thể giải thích nó mà không cần nhấn thông số ngôn ngữ. Chế độ thất bại ở đây là câu lệnh trong khối catch có thể ném một ngoại lệ. Rất có thể, việc ném một ngoại lệ trong một hàm tạo được hỗ trợ trong C#. Nhưng thực sự nói chung, bất kỳ tuyên bố có thể ném một ngoại lệ. Mà sẽ để lại biến uninitialized. Nhiệm vụ trong khối cuối cùng sẽ luôn luôn thực thi. Và sử dụng biến chưa được khởi tạo trong trường hợp đó.

Bạn sẽ cần phải suy nghĩ về những gì bạn đã xảy ra trong trường hợp đó, nếu nó có liên quan. Nhưng cách giải quyết rõ ràng là chỉ đơn giản khởi tạo biến thành null một cách rõ ràng.

Các vấn đề liên quan