2012-01-27 27 views
7

tôi có một tài sản như thế này:Thuộc tính có luôn luôn có giá trị khi không được đặt?

public Tuple<String, String>[] Breadcrumbs { get; set; } 

và tôi có một thử nghiệm tại một trong những phương pháp của tôi như thế này:

if (Breadcrumbs != null && Breadcrumbs.Length > 0) { } 

Tùy thuộc vào khi phương pháp này được gọi là, Breadcrumbs có thể không đã được thiết lập . Trong một thử nghiệm, Breadcrumbs == null giả sử thành sự thật.

Việc bỏ đặt các thuộc tính luôn có giá trị? (Sẽ luôn là null?)

Trả lời

18

Thuộc tính được tự động triển khai chưa được đặt rõ ràng bởi bất kỳ mã nào sẽ luôn có giá trị mặc định cho loại thuộc tính - không có giá trị cho loại tham chiếu. (Đối với int nó sẽ là 0, cho char nó sẽ là '\ 0' vv).

Một tính chất tự động thực hiện như thế này là chỉ tương đương với:

private PropertyType property; 
public PropertyType Property 
{ 
    get { return property; } 
    set { property = value; } 
} 

... ngoại trừ việc biến sự ủng hộ có một cái tên không kể xiết (bạn không thể đề cập đến nó trong code) do đó nó sẽ luôn bắt đầu với giá trị mặc định cho loại.

+2

+1 cho "tên không thể nói" :) –

3

Thuộc tính tự động sử dụng các trường sao lưu và được biên dịch thành các thuộc tính thông thường.

Nếu loại thuộc tính là loại tham chiếu giá trị sẽ là rỗng, nếu không phải giá trị sẽ là giá trị mặc định.

2

Biến thành viên lớp (được gọi là trường), và do đó sao lưu biến của thuộc tính, luôn được khởi tạo thành giá trị mặc định của chúng, nếu chúng không được khởi tạo rõ ràng, là null cho loại tham chiếu. Giá trị mặc định cho tất cả các loại là giá trị có biểu diễn nhị phân bao gồm tất cả các bit được đặt thành 0.

Mặt khác, C# yêu cầu bạn khởi tạo biến cục bộ một cách rõ ràng. Đó là: các biến được khai báo trong các phương thức, các hàm tạo và các trình truy cập thuộc tính và các tham số phương thức out; tức là chúng được coi là không xác định cho đến khi bạn gán cho chúng một giá trị.

+0

Rất tiếc, tôi đã mã hóa C# cho đến bây giờ theo ấn tượng rằng tôi phải khởi tạo mọi thứ hoặc mạo hiểm tìm thấy nhiều rác ngẫu nhiên. Dù vậy, tôi nghĩ tôi sẽ theo đuổi thói quen, vì vậy tôi không phạm một trong những sai lầm khủng khiếp khủng khiếp khi tôi quay trở lại C. – Oliver

+0

Trình biên dịch C# rất tốt trong việc phát hiện các biến tiềm năng chưa được khởi tạo, vì vậy đừng lo lắng quá nhiều! –

+2

@Oliver: Không, bạn sẽ không bao giờ tìm thấy rác ngẫu nhiên; quản lý bộ nhớ luôn khởi tạo nó. (Trong mã an toàn, trong mã không an toàn, bạn đang ở trên của riêng bạn. Đó là lý do tại sao nó được gọi là "không an toàn".) Tuy nhiên, C# không yêu cầu bạn khởi tạo tất cả các biến cục bộ một cách rõ ràng trước khi chúng được đọc từ; đây không phải là để ngăn cản bạn nhìn thấy rác, nó là để ngăn chặn bạn từ các lỗi. –

0

Không thể có giá trị về mặt logic một cách logic. Nó sẽ phải trả lại một cái gì đó, một số bó của 1s và 0 mà ít nhất được cho là một tham chiếu đến một Tuple<String, String>[], do đó, đến mức đó nó có một giá trị.

Đó cũng là trường hợp tất cả các trường trong lớp được đặt thành giá trị mặc định của chúng (default(T) cho bất kỳ loại nào T chúng là null cho tất cả các loại tham chiếu). Nếu không nó sẽ có thể có một đối tượng ở trong trạng thái không chỉ có ý nghĩa gì về những gì nó làm, nhưng điều đó không có ý nghĩa gì bởi các quy tắc của những gì .NET mong đợi các đối tượng cần làm. Điều này bao gồm các trường ẩn đằng sau các thuộc tính tự động.

Bây giờ, trong một số ngôn ngữ chúng ta có thể làm tương đương với điều này:

public Tuple<String, String>[] Breadcrumbs 
{ 
    get 
    { 
    Tuple<String, String>[] whatIWillSend; 
    return whatIWillSend; 
    } 
} 

Nếu đây được phép, whatIWillSend sẽ có một giá trị được xác định không phải do bất kỳ quyết định ý thức từ phía bạn, nhưng bởi những gì đã xảy ra là trong bộ nhớ vào thời điểm đó. Nó có thể là null, nó có thể là một hợp lệ Tuple<String, String>[] do trùng hợp ngẫu nhiên (nhưng không phải là một trong những bạn muốn sử dụng!), nó có thể là Dictionary<int, List<string>> mà thời gian chạy bây giờ sẽ nghĩ là thực sự là một Tuple<String, String>[] (có loại an toàn của toàn bộ hệ thống), nó có thể là một phần tư của một cấu trúc decimal. (Trong các ngôn ngữ cho phép những thứ như vậy, nó cũng có thể là một giá trị nổi tiếng mà các trình gỡ rối cho các ngôn ngữ đó được đặt trong những trường hợp này một cách chính xác để giúp tìm ra các lỗi do nó gây ra).

Đó là điều gần nhất mà chúng tôi có thể truy cập vào thuộc tính không có giá trị. Lưu ý rằng:

  1. Nó vẫn có giá trị, không phải là giá trị có ý nghĩa.
  2. Chúng tôi không được phép thực hiện việc này trong C#.
Các vấn đề liên quan