2009-09-28 33 views
5

Nếu tôi muốn thu hẹp phạm vi của một biến trong C#, tôi có thể giới thiệu thêm niềng răng - ví dụ:Phạm vi và làm thế nào để thu hẹp nó sử dụng VB.Net

class Program 
{ 
    static void Main(string[] args) 
    { 
     myClass x = new myClass(); 
     x.MyProperty = 1000; 
     Console.WriteLine("x = " + x.MyProperty); 

     { 
      myClass y = new myClass(); 
      y.MyProperty = 2000; 
      Console.WriteLine("y = " + y.MyProperty); 
     } 

     myClass y2 = new myClass(); 
     y2.MyProperty = 3000; 
     Console.WriteLine("y2 = " + y2.MyProperty); 

    } 

    class myClass 
    { 

     public int MyProperty { get; set; } 

    } 
} 

Trong ide, tôi không còn có thể tham khảo y bên ngoài phạm vi được giới thiệu bởi các niềng răng mới. Tôi đã nghĩ rằng điều này có nghĩa là biến y sẽ có sẵn để thu gom rác thải.

(nó là thú vị để lưu ý rằng khi xem mã biên dịch sử dụng phản xạ dường như không có sự khác biệt có hoặc không có dấu ngoặc bổ sung)

Có cách nào tương tự như sau để thu hẹp phạm vi khi sử dụng VB. mạng lưới? Điều này có ảnh hưởng đến khi các biến được xác định trong phạm vi bên trong có thể được thu gom rác không?

Trả lời

0

Trong C# ít nhất, nó không tạo ra bất kỳ sự khác biệt nào khi thu thập rác không được đính kèm - GC có thể làm việc khi biến được đọc lần cuối và biến không được tính là GC gốc sau thời điểm đó. Ví dụ:

object y = new object(); 
Console.WriteLine("y is still a GC root"); 
Console.WriteLine(y); 
Console.WriteLine("y is not a GC root now"); 
y = null; 
Console.WriteLine("y is still not a GC root"); 

(Về mặt thuật ngữ, biến bản thân không được thu thập, nó chỉ rằng trong khi thì coi như là "gốc" để thu gom rác, nó ngăn chặn các đối tượng nó đề cập đến từ đang được thu thập .)

Khi bạn đã có trình gỡ rối được đính kèm, GC sẽ thận trọng hơn nhiều, vì bạn có thể muốn kiểm tra giá trị của biến sau điểm đọc "bình thường" cuối cùng của nó.

Lợi ích chính của việc giảm phạm vi là rõ ràng, IMO. Nếu một biến có phạm vi hẹp, bạn có thể quên nó khi bạn không nhìn vào đoạn mã đó (giả sử nó không bị một đại biểu nắm bắt, vv).

Tôi không biết liệu VB có bất kỳ tương đương với khối lệnh không có lý do nào khác ngoài phạm vi; tương đương gần nhất có thể là câu lệnh With ... hoặc câu lệnh Do ... Loop While False, cả hai đều không thỏa đáng.

+0

liên quan đến phạm vi trợ giúp .Net đề cập đến khối Với việc xác định mức khối phạm vi và áp dụng cho bất kỳ thứ gì được xác định trong khối, nhưng không áp dụng đối tượng của khối. thu hẹp phạm vi có thể đạt được bằng cách sử dụng Với 1 cuối với hoặc Với True End With nhưng nó vẫn cảm thấy hacky ... – hitch

+0

Các hành vi GC là như nhau trong VB.NET. VB.NET không tương đương với một khối lệnh chỉ cho phạm vi - xem mục MSDN (từ câu trả lời của paintballbob) http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx – MarkJ

2

Có vẻ như không phải là cách tốt để tạo phạm vi mới trong vb, nhưng bạn có thể tạo vòng lặp chỉ chạy một lần được bảo đảm và sau đó khai báo biến của bạn bên trong vòng lặp đó.

MSDN có này để nói về cuộc đời của một biến:

Thậm chí nếu phạm vi của một biến được giới hạn trong một khối, tuổi thọ của pin vẫn là của toàn bộ thủ tục. Nếu bạn nhập khối nhiều lần trong quy trình, mỗi biến khối vẫn giữ giá trị trước đó của nó. Để tránh các kết quả không mong muốn trong trường hợp này, bạn nên khởi tạo các biến khối ở đầu khối.

src: http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx

dường như biến giảm thì chỉ bị thu gom rác thải một khi thủ tục đã hoàn tất, nhưng thậm chí sau đó thu gom rác sẽ không chạy trừ khi đống là nhận được đông đúc. Nhiều khả năng ứng dụng nhỏ không bao giờ bị thu gom rác cho đến khi ứng dụng bị đóng.

+0

Bạn đúng về phạm vi và tuổi thọ. Không hoàn toàn chính xác về việc thu gom rác thải chỉ xảy ra khi thủ tục đã kết thúc. Nó có thể xảy ra sớm hơn, xem câu trả lời của Skeet. – MarkJ

5

Điều thú vị là developerFusion C# -vb.net chuyển đổi mã chuyển đổi

{ 
    myClass y = new myClass(); 
    y.MyProperty = 2000; 
    Console.WriteLine("y = " + y.MyProperty); 
} 

để

If True Then 
    Dim y As New [myClass]() 
    y.MyProperty = 2000 
    Console.WriteLine("y = " & y.MyProperty) 
End If 

như một cách để giới hạn phạm vi. Tôi ngạc nhiên khi những điều phiền toái mang trong tâm trí paintballbob's answer

0

Tại sao không chỉ tạo ra một vài phương pháp? Phạm vi phải được xác định trong một phương thức. Một khi bạn thoát khỏi phương pháp bạn rời khỏi phạm vi - sạch sẽ và dễ dàng. Cách bạn đang làm là rất không chính thống - tôi sẽ đề nghị bạn dính vào quy ước và phương pháp sử dụng nếu bạn đang lo lắng về phạm vi creep (những gì bạn đang mô tả).

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