2009-04-21 28 views
17

Có một số sự khác biệt nội bộ giữa C# cú pháp cách đường làm thuộc tính:Có thể sử dụng biến công khai trong C# nếu nó là chỉ đọc không?

public string FirstName { get; set; } 

và chỉ cần làm biến công cộng như thế này:

public string LastName; 

tôi giả cách đầu tiên được ưu tiên và thứ hai tới tránh. Tuy nhiên, tôi thường thấy loại thuộc tính chỉ đọc này được sử dụng là một dạng của loại thứ hai ở trên:

public readonly string InternalCode; 

Đây có phải là cách thực hành tốt nhất để tạo thuộc tính chỉ đọc không?

using System; 

namespace TestProps 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Customer customer = new Customer(); 
      customer.FirstName = "Jim"; 
      customer.LastName = "Smith"; 
      customer.Show(); 
     } 
    } 

    class Customer 
    { 
     public string FirstName { get; set; } //prefered 
     public string LastName; //avoid 
     public readonly string InternalCode; //??? 

     public Customer() 
     { 
      InternalCode = "234729834723984"; 
     } 

     public void Show() 
     { 
      Console.WriteLine("{0}, {1} ({2})", LastName, FirstName, InternalCode); 
      Console.ReadLine(); 
     } 
    } 
} 

Trả lời

17

Kể từ khi ông không trả lời (chưa) và không ai khác tham chiếu này được nêu ra: Có một bài viết tuyệt vời về chủ đề này của Jon Skeet sửa đổi mình cuốn sách C# trong sâu (cung cấp cho các khoản tín dụng để Jon):

Why Properties Matter

+0

bài viết đó là hai trang trực tiếp giải quyết câu hỏi của tôi, cảm ơn! Tôi hiểu từ nó rằng Jon thậm chí sẽ không chấp nhận "công khai chỉ đọc bool IsValid;" Trừ khi, như ông đề cập ở cuối, nó là trong một lớp lồng nhau –

+1

Đối với những người trong chúng ta chỉ tìm kiếm một câu trả lời và không phải là một bài viết dài, bạn có thể thêm một cảnh báo spoiler ở đây và cho chúng tôi câu trả lời có hoặc không? – DOK

+0

Bài viết Skeet thực sự tạo ra một vài ngoại lệ, một trong số đó có thể áp dụng cho câu hỏi này. Theo bài báo, "Tôi sẽ tạo một ngoại lệ nhỏ cho các trường chỉ đọc tĩnh như string.Empty". Câu hỏi này có thể đã được sửa đổi và bằng cách di chuyển nhiệm vụ từ các nhà xây dựng lên cùng một dòng sẽ được public static readonly string InternalCode = "234729834723984"; Như vậy, nó sẽ là một "trường chỉ đọc tĩnh" giống như Skeet được mô tả. – John

1

Có. nó là OK để có một biến readonly công cộng (nó chỉ là họ có thể được khởi tạo tại thời điểm định nghĩa hoặc constructor).

ví dụ: Decimal.MaxValue

Có thuộc tính chỉ đọc công khai là tốt, nếu giá trị sao lưu thay đổi (khác với giá trị được khởi tạo).

ví dụ: Environment.TickCount

Tôi nghĩ rằng Environment.NewLine sẽ là biến chỉ đọc công khai. Vâng, nó là một tài sản công cộng (chỉ có được) và lý do có thể là duy trì khả năng tương thích trên nền tảng khác nhau.

+0

Điều gì là sai với điều này? Vui lòng đăng lý do khi bỏ phiếu xuống. Nó sẽ giúp tôi nhận ra sai lầm của tôi. Cảm ơn. – shahkalpesh

+0

Không có bình chọn từ tôi, nhưng thực sự Decimal.MaxValue là một const và không phải là một trường dụ (Đọc bài viết của Jon Skeet liên kết trong câu trả lời của tôi vì lý do không để lộ trường) –

3

Sử dụng thuộc tính cung cấp giao diện có khả năng chống thay đổi trong tương lai. Giả sử một thời gian trong tương lai, một quyết định được đưa ra để thêm tiền tố vào mã nội bộ.

Sử dụng biến đọc công khai hiển thị cấu trúc bên trong của bạn và bạn sẽ gặp khó khăn khi thêm tiền tố vào mỗi dòng bạn đã sử dụng biến nội bộ của lớp.

Sử dụng một tài sản, bạn chỉ có thể viết

sau
public string InternalCode { 
    get { return _prefix + _internalCode; } 
} 

và bạn đã hoàn tất!

+0

một khi bạn giải quyết tất cả các lỗi trình biên dịch của bạn :-) –

+0

Điều gì lỗi trình biên dịch? –

+0

Lỗi Trình sửa đổi 'chỉ đọc' không hợp lệ cho mục này –

3

Theo ý kiến ​​của tôi, bạn có thể để lộ các trường công khai (đặc biệt nếu chúng là chỉ đọc hoặc const). Có nói rằng, tôi muốn nói rằng trong ví dụ bạn đang trình bày, tôi có thể đi với tài sản vì họ sẽ cung cấp cho bạn 2 lợi thế (trên các lĩnh vực): 1) đóng gói tốt hơn và có thể cho phép bạn điều chỉnh mã của bạn trong tương lai và 2) nếu bạn đang thực hiện ràng buộc dữ liệu, thì bạn cần các thuộc tính.

0

Câu trả lời ngắn: public const là ok, readonly công không nhất thiết, get công cộng mà không thiết lập không nhất thiết. Các đối tượng không thể thay đổi mà không được chỉ định có thể được chấp nhận. Các kiểu tham chiếu nguy hiểm vì bạn vẫn có thể thay đổi các giá trị của chúng, ngay cả khi bạn không thể thay đổi tham chiếu.

Vấn đề với từ khóa chỉ đọc là nó không có nghĩa là những gì bạn muốn hiểu là một cách hợp lý chỉ đọc/không thay đổi. Nó có nghĩa là giống như "chỉ có thể được chỉ định trong constructor". Không thể thay đổi các tham chiếu, nhưng các giá trị của nó có thể. Không có từ khóa chỉ đọc "thực" được cung cấp bởi C#, thật không may. Xem thêm https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/

Thuộc tính không thể có từ khóa chỉ đọc (https://titombo.wordpress.com/2012/11/11/using-the-c-modifiers/). Như những người khác đã lưu ý, bạn có thể sử dụng thuộc tính và chỉ xác định get và no set, mặc dù bạn không thể đặt thuộc tính đó trong hàm tạo. Sử dụng tập hợp riêng tư, bạn có thể đặt thuộc tính từ annywhere trong lớp, không chỉ chỉ trong hàm tạo. Trường chỉ đọc sẽ hạn chế hơn một chút.

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