2009-10-16 39 views
7

Tôi đã đọc một số cuộc thảo luận về chủ đề này, và có điều tôi không hiểu.Property vs Function (đặc biệt là .NET)

Câu trả lời phổ biến nhất dường như là: sử dụng thuộc tính ReadOnly để trả về dữ liệu được lưu trong bộ nhớ cache, sử dụng hàm để trả về dữ liệu không được lưu trong bộ nhớ cache. Không sử dụng một thuộc tính WriteOnly, gây ra "nó không có ý nghĩa".

Không có lý do hiệu suất cho việc này. Trong IL, MyProperty tồn tại như các phương thức get_MyPropertyset_MyProperty. Lý do duy nhất rõ ràng là câu trả lời trên nên được giả định.

Ok, vậy tại sao phải bận tâm với Thuộc tính chỉ đọc? Tại sao không chỉ biến biến Public thành thay vì Riêng tư? Vậy tại sao phải bận tâm với Thuộc tính? Dữ liệu được lưu trong bộ nhớ cache -> Biến công khai, dữ liệu không được lưu trong bộ nhớ cache -> Chức năng, dữ liệu ghi -> Phụ

Hãy quên tất cả những điều trên và sử dụng Thuộc tính làm tính năng tiện dụng? Một 'mục' để Nhận và Đặt dữ liệu. Sử dụng ý thức chung để biết nếu một Nhận sẽ không trả lại dữ liệu được lưu trong bộ nhớ cache (có thể dẫn đến chậm trễ).

-Edit- Tôi thấy mọi người ít nhiều đồng ý rằng Thuộc tính là lựa chọn tốt nhất. Tôi không thể hiểu tại sao tôi lại tìm thấy rất nhiều cuộc thảo luận mà mọi người ủng hộ chống lại các Đặc tính.

+1

Điều gì, chính xác, là câu hỏi của bạn? Đoạn cuối cùng của bạn mâu thuẫn với câu hỏi của bạn hoặc cung cấp câu trả lời của riêng bạn. –

+0

Đoạn cuối cùng của tôi là cung cấp ý kiến ​​của riêng tôi. Tôi đang tìm kiếm sự đồng ý hoặc không đồng ý (với lý do được cung cấp). – Stijn

+4

http://stackoverflow.com/questions/1019571/why-do-we-use-net-properties-instead-of-plain-old-get-set-functions – Jimmy

Trả lời

13

Lý do chính đáng cho thuộc tính chỉ đọc là các giá trị được tính toán. Trong trường hợp này, không có biến nào để xuất.

Ví dụ

public class Person { 
    private readonly DateTime _birthday; 
    public int Age { get { return (DateTime.Now - _birthday).TotalYears; } } 
    ... 
} 

Trong trường hợp này cho dù để lộ _birthday như một tài sản hoặc một lĩnh vực chắc chắn là tranh cãi. Nhưng đối với các giá trị được tính toán khác như Độ tuổi, cách duy nhất để hiển thị chúng dưới dạng biến là lưu trữ chúng trong đối tượng. Trong trường hợp này có một biến phụ cho Age về cơ bản là lưu trữ thông tin dư thừa. Việc phơi bày nó dưới dạng tài sản được tính có chi phí nhỏ và tránh lưu trữ dữ liệu dư thừa

3

Có nhiều thuộc tính hơn thuộc tính tự động. Nếu bạn làm:

public int MyProp { public get; public set; } 

Sau đó, nó thực sự không có khác biệt so với

public int MyProp; 

Nhưng lợi thế lớn của cựu là bạn sau này có thể thay đổi nó thành:

public int MyProp { 
    get { 
     // Do some processing 
     return someValue; 
    } 

    set { 
     // Do some processing 
     DoMyProcess(value); 
    } 
} 

Và mã khác sử dụng đối tượng của bạn sẽ hoạt động mà không cần biên dịch lại. Nếu, thay vào đó, bạn đã sử dụng một trường công khai, mã máy khách sẽ cần phải được biên dịch lại nếu bạn muốn thay đổi nó từ một trường thành một thuộc tính.

+0

"Lợi ích" của các đặc tính này được nhấn mạnh quá mức , theo ý kiến ​​của tôi. Chắc chắn, nó là rất quan trọng đối với những người đang viết thư viện, khung, vv với một số lượng lớn "người tiêu dùng nhị phân". Nhưng đối với hầu hết các dự án .NET tôi đã làm việc, thật dễ dàng để "xây dựng lại thế giới". –

+0

@Dan: Bạn nói đúng, với 90% dự án tôi làm việc, cũng không có vấn đề gì lớn. Giống như bất cứ điều gì khác, tài sản là một công cụ - sử dụng chúng nếu chúng giúp bạn, bỏ qua chúng nếu chúng không. Tuy nhiên, các thuộc tính lý do được nhấn mạnh rất nhiều là cùng một lý do tại sao mọi người viết getters và setters trong Java, hoặc thậm chí tại sao mọi người viết 'if (0 == foo)' thay vì 'if (foo == 0)' - một cơ chế mã hóa phòng thủ trở thành một thói quen. Nhiều người cho rằng thói quen này đáng để nỗ lực. Một lần nữa, nếu nó giúp bạn, hãy sử dụng nó. –

+0

Với các thuộc tính tự động thực hiện của C# 3, tôi không thử bơi ngược dòng ở đây. Tuy nhiên, đối với hầu hết các mục đích sử dụng của tôi, một lĩnh vực sẽ hoạt động tốt - và nếu tôi cần một bộ/bộ rõ ràng, việc thay đổi thành một tài sản sẽ không có vấn đề gì vì tôi sẽ xây dựng lại mọi thứ. Có, có một vài trường hợp góc như một tham số 'ref' sẽ phá vỡ khi chuyển từ trường sang thuộc tính ... –

3

Thuộc tính là sự thay thế thuận tiện cho các hoạt động dựa trên phương pháp. Không có sự khác biệt về chức năng giữa một bộ khởi động thuộc tính-getter và một phương thức thực hiện các hành động tương tự; trong thực tế, nếu bạn nhìn vào IL bạn sẽ thấy các accessors thuộc tính được thay thế bằng các phương thức "get" và/hoặc "set".

Lý do mạnh nhất để sử dụng các thuộc tính chỉ cho phép truy cập vào các biến là đóng gói. Giả sử bạn đang viết thư viện và bạn hiển thị biến số IsBlue. Bạn phân phối thư viện, mọi người đều yêu thích và sử dụng nó.Bây giờ, đã đến lúc cho phiên bản 2 và bạn muốn làm điều gì đó khi người dùng đặt IsBlue - có thể thực hiện kiểm tra, có thể lưu vào bộ nhớ cache. Để làm điều đó, bạn sẽ phải chuyển đổi biến thành thuộc tính hoặc phương thức và thực hiện kiểm tra ở đó. Bây giờ, bạn đã phá vỡ tất cả mã máy khách của mình - biến mà họ đã truy cập không còn ở đó nữa. Nếu bạn đã thực hiện nó ban đầu như là một tài sản, bạn có thể vừa sửa đổi mã của tài sản, và giữ lại khả năng tương thích nhị phân.

1

"Dữ liệu đã lưu trong bộ nhớ cache -> Biến công khai" - ý tưởng tồi. Điều này sẽ cho phép một lớp khác sửa đổi dữ liệu được lưu trong bộ nhớ cache. Ngoài ra, việc tính toán dữ liệu cho bộ nhớ đệm có thể tốn kém: sử dụng thuộc tính chỉ đọc cho phép bạn trì hoãn việc tính toán cho đến khi thuộc tính được truy cập.

0

Hành vi được coi là không tốt để hiển thị biến của bạn từ lớp học. Thêm vào đó nếu bạn thay đổi cấu trúc của đối tượng nhưng giữ nguyên các thuộc tính của bạn, nó sẽ không ảnh hưởng đến mã sử dụng lớp của bạn.

5

Lý do # 1 = Thuộc tính có thể được sử dụng trong ràng buộc dữ liệu. Phương thức không thể.

Lý do # 2 = Khi gỡ lỗi cửa sổ xem sẽ tự động phơi bày các thuộc tính/mở rộng đối tượng. Phương pháp không được tự động theo dõi theo cách này.

Tôi nhớ đọc một nơi nào đó rằng thuộc tính đọc không được thay đổi trạng thái đối tượng. Tôi nghĩ rằng đó là một thực hành tốt để làm theo đặc biệt là xem xét lý do # 2. Ngay sau khi bạn xem một đối tượng và mở rộng nó trong đồng hồ, trạng thái đối tượng có thể được thay đổi, do đó việc gỡ lỗi trở nên khó khăn hơn.

Ngoài ra nếu tài sản đắt tiền bị ràng buộc do tai nạn, nó có thể đưa ra các vấn đề nghiêm trọng về hiệu suất. (Các thuộc tính có thể "ẩn" các thuộc tính khỏi ràng buộc dữ liệu nhưng chỉ làm cho chúng phương thức có nghĩa là bạn không phải lo lắng về nó.)

Đặc tính tiện lợi cho việc phát triển cửa sổ. Họ được "sử dụng" khác nhau trong thiết kế, vv

(đôi khi tôi chỉ tiếp xúc với một số biến Nhưng tôi đặt tên cho chúng như tôi sẽ là một tài sản Vì vậy, thay vì

Integer mCounter = 0;..

Tôi chỉ làm

Integer Counter = 0 ;.

Nếu tôi phải làm "công cụ bổ sung" tại một số điểm trong tương lai tôi có thể tạo các tài sản có cùng tên và đổi tên biến để mCounter. phải thừa nhận rằng đây là sự lười biếng trên phần của tôi và tôi không thực sự trở lại comend nó. Chỉ cần quấn nó lên trong một tài sản.)

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