2016-05-28 12 views
9

Có bất kỳ sự khác biệt nào giữa phần bổ trợ chỉ đọc và thuộc tính chỉ nhận không?C# chỉ đọc vs Nhận

dụ:

public class GetOnly 
{ 
    public string MyProp {get; } 
} 

public class ReadOnly 
{ 
    public readonly string MyProp; 
} 

Bonus: có cách nào để thực hiện một giao diện làm việc với cả hai? (để sử dụng với generics)

public interface ISomething 
{ 
    public string MyProp { get; }; 
} 

public class GetOnly : ISomething 
{ 
    public string MyProp {get; } 
} 

public class ReadOnly : ISomething //cannot implement 
{ 
    public readonly string MyProp; 
} 

Rất cám ơn trước!

+0

Bạn có thể triển khai giao diện trên lớp ReadOnly với triển khai rõ ràng –

Trả lời

7

Thoạt nhìn, thuộc tính và trường có chức năng tương đương và đối với các trường hợp sử dụng thông thường lưu trữ dữ liệu và truyền đi xung quanh thì không có nhiều khác biệt khi sử dụng chúng.

Nhưng dường như bạn đã tìm thấy một vấn đề quan trọng: Chỉ các thuộc tính mới có thể là một phần của giao diện.

có cách nào để tạo giao diện hoạt động với cả hai?

số

Bên cạnh đó, nhiều API dựa trên sự phản xạ (EF, serialization) đặc biệt tìm kiếm tài sản.

+0

Tuyệt vời! Tôi đã nhìn thấy cái nào sẽ nhẹ hơn trong bộ nhớ và chạy vào điều này đang cố gắng làm cho mọi thứ trở nên khô hơn. – robjam

+0

@robjam nếu bạn xem xét sử dụng các biến chỉ đọc thay vì chỉ nhận các thuộc tính, bạn nên xem xét không sử dụng bất kỳ phương thức nào và chỉ có một khoảng trống chính (lấy dấu mỉa mai?). Thuộc tính chỉ nhận là trường chỉ đọc riêng và khoảng trống công khai trả về giá trị. Không có gì khác. - http://tryroslyn.azurewebsites.net/#K4Zwlgdg5gBAygTxAFwKYFsB0BhA9gG31QGNkxcIRMBxVCVAJzGIG4AoUSWRFDTAGUgBHdp2jwkadOzYAHYACN8zGMXwBDECBjYYAbzZsYxmPKUrIyGAA99UVMhYBfNk6A== – Mafii

+0

Bạn quên 2 điểm quan trọng: 1) thuộc tính có thể trở thành một phần không chỉ của một giao diện, mà còn của một lớp cơ sở, và có thể được ghi đè trong một chuỗi thứ bậc từ lớp học đến lớp. 2) Chỉ có các thuộc tính có thể được sử dụng như các nguồn trong một ràng buộc WPF. –

1

Trong phần sau đây:

public class GetOnly 
{ 
    public string MyProp {get; } 
} 

MyProp là một property. Tuy nhiên, trong phần này:

public class ReadOnly 
{ 
    public readonly string MyProp; 
} 

MyPropfield. Đây là hai điều khác nhau.

có cách nào để tạo giao diện hoạt động với cả hai?

Không. Chỉ có thể đưa các thuộc tính vào giao diện. Các trường không thể.

2

Một là một trường (readonly); khác là tài sản. Giao diện không thể xác định trường, chỉ thuộc tính, phương thức, chỉ mục và sự kiện.

Cả hai chỉ có thể được gán thông qua hàm khởi tạo hoặc khởi tạo trường và không thể thay đổi sau đó.

+0

@downvoter, vui lòng để lại nhận xét về câu trả lời của tôi có gì sai; Tôi sẽ sẵn sàng cải thiện nó nếu đề xuất của bạn là hợp lệ. – CoolBots

+0

@HenkHolterman Tôi đã sửa đổi câu trả lời của mình (liên quan đến 'tập hợp cá nhân') dựa trên câu trả lời của bạn. Cảm ơn bạn! – CoolBots

6

Về cơ bản, bạn hiểu sai ý nghĩa của cả hai định nghĩa đó. Chỉ hiển thị bộ thu hút nói không có gì là về việc liệu giá trị có phải chỉ đọc hay không.

Trong khi trong ví dụ tầm thường này:

public class GetOnly 
{ 
    public string MyProp { get; } 
} 

Chúng tôi có thể nói rằng MyProp sẽ không bao giờ thay đổi giá trị của nó, chúng ta không thể luôn luôn nói rằng một tài sản getter chỉ sẽ không có giá trị của nó thay đổi. Ví dụ về trường hợp này là một trường hợp mà chúng tôi không thể xem việc triển khai GetOnly và chỉ biết về định nghĩa công khai - Ví dụ: nếu bạn đang làm việc với thư viện bên thứ ba nguồn đóng.

Một ví dụ rõ ràng hơn là thế này:

public interface ISomething 
{ 
    string MyProp { get; } 
} 

Giao diện này không nói rằng MyProp là read-only. Nó nói rằng bạn không thể thay đổi thuộc tính. Nó không nói gì về hành vi của tài sản. Thậm chí tệ hơn, nó chỉ nói rằng bạn không thể thay đổi tài sản khi đúc một cách rõ ràng là ISomething.

Đó là hoàn toàn thể thực hiện các giao diện như vậy (mặc dù giao diện duy nhất cho thấy nhiều getter):

public class GetOnly : ISomething 
{ 
    public string MyProp { get; set; } 
} 

readonly là một modifier mà thực thi một cách rõ ràng thực tế là giá trị sẽ không bao giờ thay đổi , ngoại trừ trong tuyên bố hoặc nhà xây dựng (cách xử lý các cách giải quyết như reflection).

Tuy nhiên, readonly không thể hoạt động trên thuộc tính vì thuộc tính chỉ đơn giản là cú pháp đường cho phương thức get/set . Hơn nữa, các giao diện chỉ xác định các phương thức, và như vậy bạn không thể xác định các trường (và bởi các trường mở rộng, chỉ đọc).

Vì vậy, để trả lời câu trả lời của bạn: Vâng, chúng cách nhau một thế giới và chỉ tương tự trên bề mặt.

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