2015-07-20 20 views
5

Tôi có một đối tượng với các thuộc tính được hiển thị là List<>. Tôi thường khởi tạo danh sách của tôi trong getter tài sản như sau:Khởi tạo danh sách bên trong các thuộc tính so với trong hàm tạo?

public class Foo 
{ 
    private List<bar> _barList; 

    public List<bar> 
    { 
     get 
     { 
      if(_barList == null) 
      { 
       _barList = new List<Bar>() 
      } 

      return _barList; 
     } 

     set 
     { 
      _barList = value; 
     } 
    } 

    public Foo() 
    { 
    } 
} 

Tuy nhiên, đồng nghiệp của tôi thường thích khởi tạo danh sách trong constructor lớp như sau:

public class Foo 
{ 
    public List<bar> BarList { get; set; } 

    public Foo() 
    { 
     BarList = new List<Bar>(); 
    } 
} 

Cả hai trường hợp ngăn chặn BarList khỏi bị truy cập trước nó được khởi tạo. Thứ hai có vẻ gọn gàng hơn do việc sử dụng autoproperties. Đầu tiên có vẻ như là một lựa chọn tốt hơn, vì danh sách chỉ được khởi tạo khi nó được sử dụng lần đầu tiên. Có cân nhắc nào khác mà tôi nên tính đến không? Có cách nào tốt nhất cho việc này không?

+2

Điều quan trọng là đảm bảo tính hợp lệ của trạng thái lớp học của bạn. Cả hai cách tiếp cận này mang lại kết quả tương tự bên ngoài, nhưng bên trong '_barList' được khởi tạo lười biếng của bạn có thể là null trong khi hàm khởi tạo khởi tạo' BarList' sẽ không rỗng khi ai đó cố gắng sử dụng nó trong lớp. Vâng, bên ngoài kết quả không hoàn toàn giống nhau nếu bạn bắt đầu giới thiệu các hành vi đa luồng vào phương trình. –

+1

Phương pháp "tải háo hức" và "tải chậm" thực sự. –

+1

Trong trường hợp này, về cơ bản là một câu hỏi về phong cách (và ý kiến, mặc dù). Trong C# 6.0, bạn có một cách khác để khởi tạo thuộc tính được tự động triển khai, vì [this SO answer] (http://stackoverflow.com/a/40754/1389444) hiển thị. –

Trả lời

4

Nếu bạn cần tiết kiệm bộ nhớ, chiến lược lười biếng rõ ràng là tốt hơn. Nếu việc sử dụng bộ nhớ đó không quan trọng thì chiến lược háo hức sẽ dẫn đến một mã đơn giản hơn rất nhiều. Nó là thích hợp hơn sau đó.

Nói chung, điều tốt là loại bỏ các trường hợp đặc biệt. Nó không phải là một điều tốt mà lĩnh vực danh sách có thể được null cho truy cập nội bộ.

Lưu ý rằng mã thậm chí còn ngắn hơn với C# 6 nghiêng thương mại nhiều hơn đối với giải pháp mã ngắn hơn.

Lưu ý rằng phiên bản lười biếng không phải là chủ đề an toàn cho việc thực hiện đồng thời bộ khởi động.

3

Ngoài câu trả lời của chúng tôi, có một câu trả lời khác, sử dụng C# 6.0, về câu hỏi này.

Một trong các tính năng mới là bộ khởi tạo cho các thuộc tính được tự động triển khai. Bạn sẽ viết:

public class Foo 
{ 
    public List<bar> BarList { get; set; } = new List<bar>(); 
} 

Ngoài ra, hãy xem các nhà thầu chính mới, được tìm thấy a programmers.stackexchange article.

Trình khởi tạo này sẽ được gọi là khởi tạo đối tượng. Trong các vấn đề về mức tiêu thụ bộ nhớ/hiệu suất, nó phải bằng khởi tạo thuộc tính trong hàm tạo.

+0

Sử dụng tính năng này, danh sách được khởi tạo khi lớp được khởi tạo hay C# xử lý khởi tạo "lười" cho bạn? Nếu có, điều này có vẻ như là giải pháp tốt nhất cho đến nay! – Ivan

+0

Thời gian khởi tạo lớp (hàm khởi tạo tĩnh) là không thể vì thuộc tính là một cá thể thành viên, vì vậy nó phải là thời gian khởi tạo đối tượng. –

+0

Rất tiếc, tôi muốn nói đối tượng chứ không phải lớp học. Vì vậy, tính năng này có vẻ tương đương với tùy chọn thứ hai trong OP .. hmm.Vì trong trường hợp của tôi, danh sách đôi khi không được sử dụng, tôi tự hỏi liệu việc tiết kiệm bộ nhớ có thể làm cho nó đáng để tự viết ra. – Ivan

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