Điểm của tài sản là gì?


11

Dưới đây là một số đối số cho các thuộc tính và các đối số phản đối của tôi:

Dễ sử dụng hơn so với viết phương thức getter và setter

Các cặp phương thức Getter và setter là một mùi mã. Làm cho nó dễ dàng hơn để viết những điều này cũng giống như làm cho việc trượt bài kiểm tra toán dễ dàng hơn bằng cách sử dụng biểu mẫu Scantron và điền vào tất cả các chữ C. Các đối tượng chỉ chứa trạng thái, để duy trì, không nên sử dụng getters / setters và nên tạo các đối tượng bất biến tại thời điểm tồn tại.

Điều quan trọng đối với người tiêu dùng của một đối tượng là những gì nó làm chứ không phải làm thế nào. Hành vi của nó là những gì nó làm; trạng thái của nó là làm thế nào nó làm điều đó. Nếu bạn thấy mình quan tâm đến trạng thái của một đối tượng (ngoại trừ sự kiên trì, mặc dù điều này cũng phá vỡ OO), bạn chỉ đơn giản là không làm OOP và mất đi lợi thế của nó.

Họ đưa ra một dấu hiệu sơ bộ về hiệu suất cho người tiêu dùng

Đây là một cái gì đó có thể thay đổi trong tương lai, cho bất kỳ tài sản nhất định. Giả sử trong phiên bản 1.0, truy cập PropertyX chỉ cần trả về một trường. Trong bản phát hành 1.5, nếu trường là null, PropertyX sử dụng mẫu Null Object để tạo một đối tượng null mới. Trong phiên bản 2.0, trường được xác nhận thêm bằng phương thức getter trong PropertyX.

Khi tài sản ngày càng phức tạp hơn, dấu hiệu hiệu suất của việc sử dụng một tài sản dường như ngày càng ít trung thực.

Chúng tốt hơn các lĩnh vực công cộng

Đây là sự thật. Nhưng phương pháp cũng vậy.

Chúng đại diện cho một khía cạnh khác nhau cơ bản của một đối tượng so với một phương thức và tất cả người tiêu dùng của đối tượng nên quan tâm đến điều này

Bạn có chắc chắn rằng cả hai câu trên đều đúng?

Chúng dễ gõ hơn, anh bạn

Chắc chắn, gõ myObject.Lengthdễ hơn gõ myObject.Length(), nhưng không thể sửa được với một chút cú pháp?


Tại sao sử dụng phương pháp thay vì thuộc tính?

  • Không đảm bảo hiệu suất. API sẽ vẫn trung thực ngay cả khi phương thức trở nên phức tạp hơn. Người tiêu dùng sẽ cần lập hồ sơ mã của họ nếu họ đang gặp phải các vấn đề về hiệu suất và không dựa vào từ khóa API.

  • Ít để người tiêu dùng nghĩ về. Liệu tài sản này có một setter? Một phương pháp chắc chắn không.

  • Người tiêu dùng đang suy nghĩ từ một tư duy OOP thích hợp. Là người tiêu dùng API, tôi thích tương tác với hành vi của đối tượng. Khi tôi thấy các thuộc tính trong API, nó trông rất giống trạng thái. Trên thực tế, nếu các thuộc tính làm quá nhiều, chúng thậm chí không phải là các thuộc tính, vì vậy, thực sự, các thuộc tính ở trạng thái API LÀ khi chúng xuất hiện cho người tiêu dùng.

  • Lập trình viên của API sẽ suy nghĩ sâu hơn về các phương thức có giá trị trả về và tránh sửa đổi trạng thái của đối tượng trong các phương thức đó, nếu có thể. Việc tách các lệnh khỏi các truy vấn nên được thực thi bất cứ khi nào có thể.


Vì vậy, tôi hỏi bạn, tại sao sử dụng thuộc tính thay vì phương pháp? Hầu hết các điểm trên MSDN đều có mùi mã và không thuộc về một trong hai thuộc tính hoặc phương thức.

(Những suy nghĩ này đến với tôi sau khi nghĩ về CQS.)


5
+1. Thuộc tính là các phương thức với cú pháp của các trường và điều đó không có nghĩa.
Nemanja Trifunovic

23
@Nemanja Trifunovic: Thật hoàn hảo nếu bạn đã viết type GetFoo() void SetFoo()mười nghìn lần. Trong tất cả thời gian viết mã C # tôi chưa bao giờ bị nhầm lẫn bởi một tài sản.
Ed S.

23
Âm thanh với tôi như bạn đã quyết định. Câu hỏi là gì?
Dean Harding

9
@Nemanja Trifunovic: "Getters và setters nói chung là xấu" Bạn có thể lặp lại điều đó bao nhiêu lần tùy thích, nhưng điều đó sẽ không thành sự thật. Làm thế nào về việc giải thích lý do tại sao bạn nghĩ rằng họ là xấu? Theo như SO gặp sự cố do nhập tên thuộc tính thay vì tên biến cơ bản, đó là lỗi không thể bỏ qua vì nó sẽ làm hỏng chương trình của bạn ngay khi bạn gọi thuộc tính và điều này khá hiếm. Khi nó xảy ra tôi biết chính xác những gì tôi đã làm để gây ra nó và tôi đã sửa nó trong hai giây. Tôi không thấy vấn đề.
Ed S.

3
Chỉ cần đi qua để chỉ ra @NemanjaTrifunovic rằng Tại sao các phương thức getter và setter là bài viết độc ác khá , là về javanhấn mạnh một điểm yếu của java : điểm yếu của việc không có thuộc tính . (do đó thể hiện quá nhiều chi tiết thực hiện) cắn cắn đuôi của chúng tôi ở đây. (nên có tiêu đề getters và setters là xấu trong java, vì chúng tôi không có tiêu chuẩn suy nghĩ tốt về những điều đó )
ZJR

Câu trả lời:


44

Tại sao nó là "phương pháp chống lại tài sản"? Một phương pháp làm một cái gì đó. Một tài sản là, một thành viên của một đối tượng. Chúng là những thứ hoàn toàn khác nhau, mặc dù hai loại phương thức thường được viết - getters và setters - tương ứng với các thuộc tính. Vì việc so sánh các thuộc tính với các phương thức nói chung là không có ý nghĩa, tôi sẽ cho rằng bạn muốn nói về getters / setters.

Các cặp phương thức Getter và setter là một mùi mã.

Không nhất thiết, tôi tranh luận, nhưng dù bằng cách nào thì đây không phải là vấn đề của getters / setters so với tài sản mà là vấn đề liệu có nên sử dụng một trong hai. Cũng lưu ý rằng bạn có thể bỏ qua setXphần giống như bạn có thể tạo các thuộc tính chỉ đọc.

Điều quan trọng đối với người tiêu dùng của một đối tượng là những gì nó làm chứ không phải làm thế nào. Hành vi của nó là những gì nó làm; trạng thái của nó là làm thế nào nó làm điều đó. Nếu bạn thấy mình quan tâm đến trạng thái của một đối tượng (ngoại trừ sự kiên trì, mặc dù điều này cũng phá vỡ OO), bạn chỉ đơn giản là không làm OOP và mất đi lợi thế của nó.

Một thái độ nghi vấn cao. Nếu GUI muốn xuất dữ liệu do a giữ DataStuffManagerImpl, thì nó cần lấy số đó từ nó bằng cách nào đó (và không, nhồi nhét một nửa ứng dụng vào lớp widget không phải là một tùy chọn).

Khi tài sản ngày càng phức tạp hơn, dấu hiệu hiệu suất của việc sử dụng một tài sản dường như ngày càng ít trung thực.

[Phương pháp có] Không đảm bảo hiệu suất. API sẽ vẫn trung thực ngay cả khi phương thức trở nên phức tạp hơn. Người tiêu dùng sẽ cần lập hồ sơ mã của họ nếu họ đang gặp phải các vấn đề về hiệu suất và không dựa vào từ khóa API.

Trong hầu hết các trường hợp, tất cả logic xác thực, v.v ... vẫn có hiệu quả O (1), hoặc nói cách khác là không thể phủ nhận về chi phí. Nếu không, có lẽ bạn đã đi quá xa và đã đến lúc thay đổi. Và một getX()phương pháp thường được coi là rẻ như là tốt!

Chắc chắn, gõ myObject.Lipse dễ hơn gõ myObject.Ldrops (), nhưng không thể sửa được với một chút đường cú pháp?

Tính chất đường cú pháp.

Ít để người tiêu dùng nghĩ về. Liệu tài sản này có một setter? Một phương pháp chắc chắn không.

"Có một setter cho getter này?" Cùng một sự khác biệt.

Lập trình viên của API sẽ suy nghĩ sâu hơn về các phương thức có giá trị trả về và tránh sửa đổi trạng thái của đối tượng trong các phương thức đó, nếu có thể. Việc tách các lệnh khỏi các truy vấn nên được thực thi bất cứ khi nào có thể.

Tôi không chắc những gì bạn đang cố nói với chúng tôi ở đây. Đối với tài sản, có một luật bất thành văn thậm chí còn mạnh mẽ hơn để không gây ra tác dụng phụ.


3
+1, và nó không phải là luật bất thành văn. Hướng dẫn sử dụng tài sản trên MSDN đã được viết với nhiều người khác. Tôi nghĩ OP nên thông qua họ để làm cho mình rõ ràng về nhiều nghi ngờ. Và tôi không thể đăng một liên kết ở đây vì tôi đang viết nó từ điện thoại của mình, nhưng hướng dẫn nên dễ tìm.
cơn bão


@delnan: Tính chất không phải là cú pháp đường. Các thuộc tính có thể được xử lý như các trường (chúng có thể được sử dụng làm mục tiêu gán, nếu chúng có setter). Phương pháp không thể.
xofz

1
@SamPearson: obj.x = yánh xạ tới obj.setX(y)obj.xánh xạ tới obj.getX(). Nó khác nhau như thế nào?

1
@SamPearson bạn có thể thay đổi mức độ hiển thị của trình thiết lập thuộc tính và getter độc lập với nhau. Tôi sử dụng điều này mọi lúc với các đối tượng Entity Framework của tôi: setters của tôi được bảo vệ (vì vậy chỉ khung có thể đặt giá trị). Vì vậy, hoàn toàn khả thi khi nói int length = myObject.Lipse mà không cho phép myObject.Lipse = 10
Michael Brown

19

Các cặp phương thức Getter và setter là một mùi mã.

Đó là một giả định sai lầm và hoàn toàn không chính xác. Các phương thức Get / Set là một cách để đóng gói một thành viên dữ liệu và hoàn toàn không phải là "mùi mã". Tôi thực sự ghét cách một số người ném vào cụm từ "mùi mã", nhưng dù sao thì ...

Đây là một cái gì đó có thể thay đổi trong tương lai, cho bất kỳ tài sản nhất định. Giả sử trong phiên bản 1.0, truy cập PropertyX chỉ cần trả về một trường. Trong bản phát hành 1.5, nếu trường là null, PropertyX sử dụng mẫu Null Object để tạo một đối tượng null mới. Trong phiên bản 2.0, trường được xác nhận thêm bằng phương thức getter trong PropertyX.

Khi tài sản ngày càng phức tạp hơn, dấu hiệu hiệu suất của việc sử dụng một tài sản dường như ngày càng ít trung thực.

Nghe giống như một API được thiết kế kém, tôi không thấy đó là lỗi của cú pháp thuộc tính.

Các thuộc tính trong C # chỉ đơn giản là đường cú pháp cho một mô hình rất phổ biến giúp cuộc sống của chúng ta trở thành lập trình viên dễ dàng hơn một chút. Tuy nhiên, những ngày này, nếu bạn muốn sử dụng dữ liệu ràng buộc, bạn "phải" sử dụng các thuộc tính, vì vậy chúng bây giờ nhiều hơn một chút so với đường cú pháp. Tôi đoán tôi thực sự không đồng ý với bất kỳ điểm nào của bạn và tôi không hiểu tại sao bạn không thích một tính năng ngôn ngữ hỗ trợ trực tiếp một mẫu chung.


1
Tôi sẽ đưa ra một tiền thưởng để đưa ra một thuật ngữ tốt hơn mùi mã. Chỉ cần đọc một cuốn sách về tái cấu trúc nơi nó được sử dụng khoảng một nghìn lần. Nó giống như móng tay trên bảng phấn.
JeffO

1
@Jeff O: Vâng, tôi thấy rằng những người dường như ném thuật ngữ đó xung quanh thường không có nhiều kinh nghiệm.
Ed S.

6
@Jeff O và @Ed S: IME, "mùi mã" đã trở thành thuật ngữ mà mọi người sử dụng khi họ thực sự có nghĩa là "Tôi không thích nó, nhưng tôi thực sự không có lý do"
Steven Evers

3
@SnOrfus: Đúng, hoặc khi họ giữ quan điểm "tôn giáo" thường ít có ý nghĩa trong thực tế, như "một phương pháp không bao giờ nên có nhiều hơn X số dòng" , mà thường chỉ là sự lặp lại của một cái gì đó họ đọc ở đâu đó.
Ed S.

1
Việc sử dụng các phương thức getter / setter không phù hợp là một mùi mã, nhưng cũng nên sử dụng bất cứ thứ gì không phù hợp . Ngay cả khi mọi thứ có các trường hợp sử dụng hẹp, sử dụng những thứ như vậy cho các trường hợp sử dụng đó không nên được coi là một mùi mã. Việc tạo ra setters cho mọi thứ không nên là một thói quen mù quáng, nhưng người ta không nên ngại đưa chúng vào khi thích hợp. Điều cần thiết là cân bằng sự hữu ích cho khách hàng về khả năng thay đổi trạng thái, so với việc có thể tìm hiểu trong tương lai trạng thái trước đó là gì (dễ dàng nếu trạng thái là bất biến). Cả hai đều hữu ích, nhưng mã phải chọn một.
supercat

10

Tiền đề của bạn là sai.

Các tài sản không phải là một hợp đồng để thực hiện hoặc thực hiện nội bộ hoặc bất cứ điều gì.
Các thuộc tính là các cặp phương thức đặc biệt, về mặt ngữ nghĩa đại diện cho một thuộc tính, nếu bạn muốn. Và do đó, hợp đồng duy nhất là, một tài sản hoạt động như bạn mong đợi một thuộc tính để hành xử.
Nếu tôi yêu cầu màu của một đối tượng, tôi sẽ không đưa ra giả định liệu nó có được bởi một truy cập trường đơn giản hay liệu nó có được tính đúng lúc hay không.
Toàn bộ vấn đề là, có khả năng phơi bày hành vi của một thuộc tính bằng cách sử dụng các phương thức, trong khi nó trong suốt đối với người tiêu dùng giao diện, cho dù bạn đang sử dụng một trường hoặc người truy cập.

Có các thuộc tính (và thực sự che giấu việc triển khai của chúng, vì các thuộc tính trái ngược với các trường) là một tính năng khai báo mạnh mẽ , là cơ sở để có các trình kiểm tra đối tượng trực quan và tạo chế độ xem tự động khác, để liên kết dữ liệu và nhiều thứ hữu ích khác. Và quan trọng nhất, nó rõ ràng cũng vận chuyển thông tin này cho các lập trình viên đồng nghiệp của bạn.


6

Người tiêu dùng đang suy nghĩ từ một tư duy OOP thích hợp. Là người tiêu dùng API, tôi thích tương tác với hành vi của đối tượng. Khi tôi thấy các thuộc tính trong API, nó trông rất giống trạng thái. Trên thực tế, nếu các thuộc tính làm quá nhiều, chúng thậm chí không phải là các thuộc tính, vì vậy, thực sự, các thuộc tính ở trạng thái API LÀ khi chúng xuất hiện cho người tiêu dùng.

Một tài sản được coi là một nhà nước. Nếu mã setter hoặc getter bên dưới thay đổi để thêm đáng kể vào quá trình xử lý cần thiết để thiết lập hoặc lấy trạng thái thì thực sự đó không còn là thuộc tính và bạn nên thay thế nó bằng các phương thức. Điều này tùy thuộc vào bạn là nhà phát triển mã.

Đặt quá nhiều mã (bao nhiêu là quá nhiều phụ thuộc) vào mã setter hoặc getter là sai, nhưng chỉ vì nó không phải là lý do để loại bỏ mẫu trong mọi trường hợp.


6

Một điều bạn đang thiếu, và tôi không biết liệu đây là do sự thiếu hiểu biết hay nếu bạn cố tình bỏ qua chi tiết này, đó là các thuộc tính LÀ phương thức.

Khi bạn sử dụng cú pháp thuộc tính của C #, trình biên dịch lặng lẽ tạo các phương thức getter và setter với siêu dữ liệu cho biết các ngôn ngữ hiểu các thuộc tính như một tính năng cú pháp hạng nhất để xử lý chúng như vậy. Trên thực tế, đó là đường cú pháp mà bạn yêu cầu. Một vài ngôn ngữ có thể chạy trên CLR không hoàn toàn ẩn chi tiết này với bạn (Boo, nếu bộ nhớ phục vụ cho tôi và một số triển khai Lisp), và bạn có thể gọi rõ ràng các getters và setters.

Các thuộc tính đôi khi có tác dụng phụ, như kích hoạt các sự kiện thông báo thay đổi (ví dụ INotifyPropertyChanged) hoặc đánh dấu một thể hiện của một lớp là bẩn. Đây là nơi chúng có giá trị thực sự của chúng, mặc dù việc tạo ra chúng là công việc nhiều hơn một chút (ngoại trừ trong Boo, có macro hiểu biết cú pháp).

Bây giờ, câu hỏi rộng hơn là liệu các phương thức getter và setter trên thực tế có phải là một điều tốt hay không. Có sự đánh đổi rõ ràng; nếu bạn có các phương thức trình biến đổi, mã của bạn vốn đã ít song song hơn, vì bây giờ bạn phải xử lý các vấn đề đồng bộ hóa luồng. Và hoàn toàn có khả năng bạn sẽ có nguy cơ vi phạm Luật Demeter khi sử dụng các phương thức của trình biến đổi (cho dù được gọi là các thuộc tính hoặc phương thức getter / setter; chúng tương đương nhau), vì nó rất thuận tiện để làm như vậy.

Nhưng đôi khi đó là điều đúng đắn. Đôi khi vấn đề của bạn là lấy dữ liệu từ một số nguồn, thay đổi một chút, trình bày dữ liệu cập nhật cho người dùng và lưu các thay đổi. Thành ngữ đó được phục vụ tốt bởi các thuộc tính. Như bài viết của Allen Holub nói, chỉ vì getters và setters có vấn đề không có nghĩa là bạn không bao giờ nên sử dụng chúng. (Vẹt trừu tượng Guruspeak coi có hại). Ngay cả khi bạn làm theo cách tiếp cận Lớp / Trách nhiệm / Cộng tác viên, bạn vẫn sẽ tiếp tục tiết lộ thông tin hoặc trình bày thông tin cho ai đó; điểm quan trọng là giảm thiểu diện tích bề mặt của sự vướng víu.

Mặt trái của các đặc tính là rất dễ để có một đối tượng khác tận dụng lợi thế của chúng. Nhược điểm của các thuộc tính là rất dễ để có một đối tượng khác lợi dụng chúng và bạn không thể dễ dàng ngăn chặn điều đó.

Đột biến đối tượng có ý nghĩa ở lớp trình điều khiển, ví dụ, trong một kiến ​​trúc MVC. Đó là cộng tác viên của bạn. Quan điểm của bạn cũng là một cộng tác viên, nhưng nó không nên trực tiếp làm thay đổi đối tượng của bạn, bởi vì nó có trách nhiệm khác nhau. Đưa mã trình bày vào các đối tượng kinh doanh của bạn không nhất thiết là cách đúng để tránh các getters / setters.

Phương trình thay đổi một chút nếu bạn sử dụng chức năng, thay vì trừu tượng OO, trừu tượng, thường tạo ra các bản sao của một đối tượng "bản ghi" với một vài thay đổi khá nhỏ, mặc dù không miễn phí. Và này, nếu bạn đang cố gắng để có được sự đảm bảo về hiệu suất, các thuộc tính thường dễ dự đoán hơn là lười xây dựng lại một bộ sưu tập bất biến.


5

Một lý do quan trọng khác trong cuốn sách của tôi để sử dụng các thuộc tính là chúng có thể tăng khả năng đọc rất nhiều.

account.setBalance(Account.getBalance()+deposit);

rõ ràng là ít đọc hơn

account.Balance += deposit;

6
Ngoại trừ Số dư đó không phải là tài sản vì chắc chắn có logic kinh doanh quan trọng liên quan đến việc thay đổi nó (kiểm tra thấu chi; phí dịch vụ; giao dịch hồ sơ, v.v.) Điểm dễ đọc của bạn là hoàn toàn hợp lệ nếu áp dụng cho một ví dụ khác ( Nhiệt độ, BackgroundColour, v.v.)
Kate Gregory

9
Tại sao không tài khoản. Kho (số tiền)?
xofz

4
@Sam Pearson: +1. Một ví dụ hoàn hảo về lý do tại sao getters / setters thường chỉ ra thiết kế kém.
Nemanja Trifunovic

4

Bạn có quan điểm tôn giáo gần như ngược lại với tôi :)

Khi tôi chuyển từ Delphi sang Java, việc thiếu các thuộc tính là một vấn đề rất lớn đối với tôi. Tôi đã quen với việc khai báo một thuộc tính và chỉ trực tiếp vào một biến riêng hoặc viết một getter (được bảo vệ) và setter sau đó "sửa chữa" chúng cho thuộc tính. Điều này gói gọn tài sản và kiểm soát cách nó nên được truy cập một cách rõ ràng rõ ràng. Bạn có thể có một thuộc tính chỉ đọc để tính tổng khi truy cập và gọi nó là "Tổng" chứ không phải "_getTotal ()" hoặc các balloch tương tự. Điều đó cũng có nghĩa là bạn có thể hạn chế quyền truy cập vào các thuộc tính bằng cách làm cho chúng được bảo vệ trong lớp cơ sở trừu tượng sau đó chuyển chúng sang công khai hoặc xuất bản trong các lớp con.

Đối với tôi, các thuộc tính là một cách thiết lập tự nhiên và biểu cảm hơn và có được trạng thái của đối tượng. Dựa vào các quy ước mã hóa không ràng buộc là "mùi mã" hơn bất cứ thứ gì bạn đang chỉ trích các thuộc tính. Ngoài ra, như những người khác đã nói, việc sử dụng các thuộc tính được thiết kế tồi và sử dụng các lỗi của nó để thử và loại bỏ khái niệm về các đặc tính nói chung là một hình thức cực kỳ tồi tệ. Có thể bạn chỉ thấy việc sử dụng tài sản không tốt và cho rằng đó là cách tôi cho rằng nhưng bạn nên nghiên cứu thêm trước khi trở nên quá giáo điều.


+1 Đó thực sự là một công dụng thực sự của một tài sản. Câu trả lời chính xác. " Điều đó cũng có nghĩa là bạn có thể hạn chế quyền truy cập vào các thuộc tính bằng cách bảo vệ chúng trong lớp cơ sở trừu tượng sau đó chuyển chúng sang công khai hoặc xuất bản trong các lớp con. "
Karthik Sreenivasan

Delphi lạm dụng thuộc tính quảng cáo nauseam. Bạn không sắp xếp danh sách, bạn đặt thuộc tính của nó sorted thành true. Vì vậy, thiết lập nó để falsecung cấp cho bạn danh sách ban đầu. : D Hoặc nó ngẫu nhiên trộn nó? : D Hoặc bất cứ điều gì, nó chỉ là ngu ngốc. Ngoài ra, nó rất chậm so với một bộ được sắp xếp thích hợp. Các thuộc tính không tệ, nhưng tôi đã học cách sử dụng chúng một cách tiết kiệm (cho đến khi khá hài lòng với getter và setters; Tôi đang sử dụng chủ yếu là Java).
maaartinus

1

Một trong những lý do các thuộc tính được giới thiệu trong Khung công tác Java là để cho phép tích hợp với IDE - bạn có thể kéo các thành phần đó vào IDE và chỉnh sửa các thuộc tính bằng các trình soạn thảo thuộc tính.

(hồi đó họ chỉ là những người thu hút và setters thông thường - và chỉ được xác định bởi quy ước đặt tên - và điều này thực sự có mùi)

Ngày nay thậm chí còn có nhiều trường hợp các thuộc tính được truy cập và sửa đổi không thông qua mã thông thường - chẳng hạn như trong khi gỡ lỗi.


1

Một góc độ khác - họ thực sự đến từ VB. Hãy nhớ rằng, trở lại trong những ngày đen tối của thế kỷ 20 khi .NET được hình thành, một điểm nhấn lớn là nó dễ dàng thay thế cho VB để các lập trình viên VB của bạn có thể kéo và thả mọi thứ vào các biểu mẫu web. VB có các thuộc tính vì vậy bạn cần giữ tính năng đó để mọi thứ được dịch đúng.


1
Anders Heljsberg đã thiết kế C # (và một số IL) và cũng thiết kế Delphi - có thuộc tính.
Jesse C. Choper

1

Có ít nhất hai mục đích cho các thuộc tính:

  • Chúng giống nhau về mặt khái niệm với các trường ngay cả khi chúng được triển khai khác nhau. Một getter không nên thay đổi trạng thái của đối tượng và không có tác dụng phụ. Một setter chỉ nên thay đổi trạng thái theo cách tương tự về mặt khái niệm với sửa đổi một trường và không có tác dụng phụ khác.

  • Chúng giống nhau về mặt cú pháp với các trường công khai (có thể chỉ đọc). Điều này có nghĩa là một trường công cộng có thể được thay đổi thành một tài sản mà không phá vỡ người gọi ở cấp nguồn.


Có, nhưng lưu ý từ "nên". Không có gì về các thuộc tính ngăn cản các getters có tác dụng phụ và trên thực tế tôi đã thấy nhiều trường hợp như vậy.
Nemanja Trifunovic

1
Thay đổi trường công khai thành thuộc tính sẽ phá vỡ tính tương thích nhị phân, mã tiêu thụ sẽ phải được biên dịch lại - mặc dù không được sửa đổi mà tôi đoán là những gì bạn đang nhận được :)
MattDavey

@MattDavey: Cảm ơn. Đó là những gì tôi muốn nói. Đã chỉnh sửa.
dsimcha
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.