2011-09-19 6 views
5

Tôi vừa mới biết về việc sử dụng các biến tĩnh cục bộ trong VB.NET và tự hỏi về khả năng sử dụng của nó trong các thuộc tính tải lười.Sử dụng biến cục bộ tĩnh trong thuộc tính tải lười trong VB.NET

Hãy xem xét mã ví dụ sau.

Public Class Foo 
    Implements IFoo 
End Class 

Public Interface IFoo 
End Interface 

Public Class Bar 

    Private _fooImplementation As IFoo 
    Public ReadOnly Property FooImplementation As IFoo 
    Get 
     If _fooImplementation Is Nothing Then _fooImplementation = New Foo 
     Return _fooImplementation 
    End Get 
    End Property 
End Class 

Đây sẽ là một thuộc tính tải lười giản dị, đơn giản. Bạn thậm chí có thể muốn sử dụng lớp Lazy chung để có được (theo như tôi biết) hành vi tương tự.

Bây giờ, hãy xem xét thuộc tính trong khi sử dụng biến tĩnh.

Public Class Bar 

    Public ReadOnly Property FooImplementation As IFoo 
    Get 
     Static _fooImplementation as IFoo = New Foo 
     Return _fooImplementation 
    End Get 
    End Property 
End Class 

Theo như tôi có thể thấy, đây có một vài ưu điểm so với việc thực hiện bình thường, chủ yếu do bạn không thể truy cập vào các biến bên ngoài của tài sản, cũng như không cần phải sử dụng một biến bổ sung.

Câu hỏi của tôi với bạn là: Cách nào trong số đó là cách "đúng" để thực hiện? Tôi biết rằng các biến tĩnh có chi phí bổ sung, nhưng nó có đủ tệ để tạo ra, theo ý kiến ​​cá nhân của tôi, mã không rõ ràng có thể bị lạm dụng dễ dàng hơn không? Bạn mất bao nhiêu hiệu suất so với phương pháp "truyền thống"? Làm thế nào nó quan trọng đối với các lớp học nhỏ so với các nhà máy lớn?

Xin cảm ơn trước.

Trả lời

3

Từ khóa Tĩnh có khá nhiều chi phí, trình biên dịch tạo ra một phần lớn IL để triển khai. Những gì nó không làm điều đó đoạn 1 của bạn không làm là đảm bảo rằng luồng không gây ra vấn đề. Nếu đó không phải là mối quan tâm thì đoạn 1 của bạn là giá rẻ hơn lot. Không chỉ vì nó có ít IL hơn nhiều mà còn bởi vì nó sẽ được inlined. Một getter với Static sẽ không bao giờ được inline vì nó chứa mã Try/Finally.

Nếu bạn đang nhắm mục tiêu .NET 4 thì bạn chắc chắn nên xem qua lớp Lười biếng (Of ​​T).

+0

+1 Đồng ý, đặc biệt là sau khi xem những gì tĩnh tạo ra. – tcarvin

+0

Để tham khảo của người khác, [đây là một câu trả lời khác] (http://stackoverflow.com/a/12202349/4889167) từ Hans Passant mà đi vào chi tiết hơn. –

1

Câu hỏi đó đủ thú vị để tôi tìm câu trả lời ... VB.NET thực thi tĩnh như thế nào. Dưới đây là C# equivilent:

public class Bar 
    { 
    [SpecialName] 
    private IFoo \u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation; 
    [SpecialName] 
    private StaticLocalInitFlag \u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init; 

    public IFoo FooImplementation 
    { 
     get 
     { 
     Monitor.Enter((object) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init); 
     try 
     { 
      if ((int) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State == 0) 
      { 
      this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State = (short) 2; 
      this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation = (IFoo) new Foo(); 
      } 
      else if ((int) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State == 2) 
      throw new IncompleteInitialization(); 
     } 
     finally 
     { 
      this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init.State = (short) 1; 
      Monitor.Exit((object) this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init); 
     } 
     return this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation; 
     } 
    } 

    [DebuggerNonUserCode] 
    public Bar() 
    { 
     this.\u0024STATIC\u0024get_FooImplementation\u0024200122C\u0024_fooImplementation\u0024Init = new StaticLocalInitFlag(); 
    } 
    }