2010-02-19 26 views
8

Khi tài sản có một số loại bộ sưu tập nhưProperties của bộ sưu tập kiểu

public IList<MyItemClass> MyList{ get; } 

IMHO, nó tốt hơn để trở lại bộ sưu tập trống thay vì giá trị null.
Có nhiều cách để thực hiện chức năng như vậy.

public IList<MyItemClass> MyList{ get; private set; } 
public MyClass(){ 
    MyList = new List<MyItemClass>(); 
} 

Cách này cho phép giảm số lượng trường lớp, nhưng bạn cần phải đặt mã trong mỗi hàm tạo.

private List<MyItemClass> _myList = new List<MyItemClass>(); 
public IList<MyItemClass> MyList{ get{ return _myList; } } 

Đây là cách tiêu chuẩn. Nhưng khi ai đó viết một cái gì đó cho mã của bạn, anh ta có thể sử dụng trường riêng thay vì thuộc tính và bạn có thể nhận được một số lỗi khi bạn refactor có được hành động.

private List<MyItemClass> _myList; 
public IList<MyItemClass> MyList{ get{ return _myList??(_myList = new List<MyItemClass>()); } } 

Và đây là biến thể của cách trước đó với tải chậm.

Bạn muốn trở lại làm giá trị mặc định cho bộ sưu tập là gì? Nếu đây là bộ sưu tập trống, làm thế nào để bạn thực hiện nó?

Trả lời

2

Từ .NET Design Guidelines:

Bạn cung cấp các giá trị mặc định hợp lý cho tất cả các tài sản, đảm bảo rằng giá trị mặc định không gây ra một lỗ hổng bảo mật hoặc một thiết kế cực kỳ hiệu quả.

Mở rộng nguyên tắc này và kết hợp nó với các Principle of Least Surprise nên làm cho nó rất rõ rằng bạn nên luôn trả về một bộ sưu tập trống thay vì null.

Tại sao đặt gánh nặng kiểm tra giá trị rỗng vào người gọi khi bạn có thể cung cấp giá trị mặc định hợp lý, trực quan?

Toàn bộ điểm đóng gói là thực hiện công việc tại một địa chỉ . Nó có thể làm cho việc triển khai lớp cụ thể phức tạp hơn một chút, nhưng nó làm cho việc sử dụng API của nó đơn giản hơn.

Trong hầu hết các trường hợp tôi thực hiện bộ sưu tập như một bất biến trong các loại bao gồm:

public class MyClass 
{ 
    private readonly List<Foo> foos; 

    public class MyClass() 
    { 
     this.foos = new List<Foo>(); 
    } 
} 

Thông báo việc sử dụng các từ khóa readonly đảm bảo rằng một khi thiết lập, danh sách không bao giờ có thể được thay thế hoặc nulled ra (nhưng nó vẫn có thể được đặt lại). Điều này bảo vệ danh sách như là một bất biến của lớp, trong đó bảo vệ tôi từ viết kiểm tra null trong phần còn lại của mã của tôi.

Tải trọng lười cũng là thành ngữ mã hóa hợp lệ, nhưng tôi chỉ sử dụng nó khi tôi cần nó một cách rõ ràng.

0

Tùy chọn 2 (cách tiêu chuẩn) và tránh vấn đề tái cấu trúc bằng cách đảm bảo kiểm tra đơn vị của bạn kiểm tra danh sách trống được trả lại khi bạn mong đợi.

0

Tôi thích biến thể thứ hai vì nó rõ ràng hơn và giảm kích thước của hàm tạo. Nhưng thường làm cho lĩnh vực này readonly:

private readonly List<MyItemClass> _myList = new List<MyItemClass>(); 
1

Trở null thực sự là không lý tưởng. Đối với lựa chọn thay thế; nó phụ thuộc vào việc sử dụng. IMO, phiên bản này (sao chép từ các bài chính) là đơn giản nhất nhưng không tất cả mọi thứ chúng ta cần:

private List<MyItemClass> _myList = new List<MyItemClass>(); 
public IList<MyItemClass> MyList { get { return _myList; } } 

và là một lợi thế, nó sẽ làm việc với XmlSerializer, nơi-như bất cứ điều gì với một private setsẽ không công việc (một lỗi; nó thấy setter nhưng không nhận thấy nó không thể sử dụng nó).

Cách tiếp cận lười biếng thường vượt quá IMO, như trong hầu hết các trường hợp thú vị, bạn vẫn sẽ phổ biến danh sách.

1

Tôi thường sử dụng biến thể nơi bạn khởi tạo danh sách trong hàm tạo. Điều này có thể làm cho hàm tạo càng "cồng kềnh" hơn, nhưng trách nhiệm của nhà thầu là xây dựng một đối tượng là. Thiết lập các giá trị mặc định tốt là IMHO hoàn toàn trong phạm vi trách nhiệm của nó. Ngoài ra, như là một tiền thưởng bạn không phải lo lắng về các lĩnh vực tư nhân mà làm cho mã trông sạch hơn.

Chắc chắn, việc tái cấu trúc không nhận được ít khó hơn, nhưng không đáng kể. Đừng quên rằng bạn có thể kết nối các nhà xây dựng của bạn (phần lớn thời gian) vì vậy ngay cả khi bạn có một số nhà xây dựng, bạn sẽ chỉ có thể viết mã khởi tạo một lần.

Đừng quên ghi lại rằng giá trị mặc định là bộ sưu tập trống. Và đặt trường sưu tập thành chỉ đọc là thực hành tốt trừ khi bạn có lý do chính đáng để đặt lại sau.