2009-03-02 38 views
104

Câu hỏi nhanh: Khi nào bạn quyết định sử dụng các thuộc tính (trong C#) và khi nào bạn quyết định sử dụng các phương thức?Các thuộc tính và phương pháp

Chúng tôi đang bận rộn có cuộc tranh luận này và đã tìm thấy một số lĩnh vực mà nó gây tranh cãi cho dù chúng ta nên sử dụng một tài sản hoặc một phương pháp. Một ví dụ là:

public void SetLabel(string text) 
{ 
    Label.Text = text; 
} 

Trong ví dụ, Label là điều khiển trên trang ASPX. Có một nguyên tắc có thể điều chỉnh quyết định (trong trường hợp này) liệu có nên biến phương thức này thành tài sản hay không.

Tôi sẽ chấp nhận câu trả lời chung và toàn diện nhất, nhưng điều đó cũng liên quan đến ví dụ mà tôi đã đưa ra.

+2

-1 câu hỏi này đã được hỏi và trả lời trước: http://stackoverflow.com/questions/164527/exposing-member-objects-as-properties-or-methods-in-net – Element

+0

Phương thức/trường/thuộc tính ưu và khuyết điểm có thể tạo ra các cuộc tranh luận dài; một số sử dụng chung cho các thuộc tính: khi bạn muốn các trường riêng tư/được bảo vệ nhưng đồng thời bạn muốn hiển thị chúng. Sử dụng khác là không chỉ có các câu lệnh mà còn cả các biểu thức (các hành động nếu bạn thích) ngay cả khi kiểm tra 'if()' (theo MSDN). Nhưng điều này là khó khăn vì người dùng không phải lúc nào cũng biết chi phí xử lý đằng sau việc truy cập biến (thuộc tính) (tức là mã không có sẵn) và vì lý do nghiêm ngặt, người dùng phải đánh giá tài sản. Oh, và một "tiền thưởng" bạn không thể sử dụng con trỏ với các thuộc tính. – mireazma

Trả lời

111

Từ phần Choosing Between Properties and Methods của Hướng dẫn thiết kế cho phát triển Class Libraries:

Nói chung, phương pháp đại diện cho hành động và tính chất đại diện cho dữ liệu. Các thuộc tính có nghĩa là được sử dụng như các trường, có nghĩa là các thuộc tính không được phức tạp tính toán hoặc tạo ra các hiệu ứng phụ. Khi nó không vi phạm các nguyên tắc sau, hãy xem xét sử dụng một thuộc tính, chứ không phải là một phương thức, bởi vì các nhà phát triển ít kinh nghiệm tìm thấy các thuộc tính dễ sử dụng hơn.

+3

Trong khi tôi đồng ý với phần lớn điều đó, tôi không nghĩ rằng phần về tác dụng phụ là đúng. Ví dụ, "Màu" thường là một thuộc tính của một đối tượng, và nó có các tác dụng phụ rõ ràng (thay đổi màu sắc của một đối tượng). Thay đổi các thuộc tính có tác dụng phụ rõ ràng của việc thay đổi trạng thái đối tượng. –

+33

Mystere Man changing Color là hiệu ứng mong muốn không có tác dụng phụ. Tác dụng phụ là cái gì đó không có ý định trong hành động chính. –

+2

@Mystere Man: definelty thay đổi màu sắc không phải là một tác dụng phụ, tôi đồng ý hoàn toàn với câu trả lời này –

47

Có, nếu tất cả những gì bạn đang làm là nhận và thiết lập, hãy sử dụng thuộc tính.

Nếu bạn đang làm điều gì đó phức tạp có thể ảnh hưởng đến một số thành viên dữ liệu, một phương pháp thích hợp hơn. Hoặc nếu getter của bạn có tham số hoặc setter của bạn mất nhiều hơn một tham số giá trị.

Ở giữa là khu vực màu xám, nơi dòng có thể bị mờ một chút. Không có quy tắc cứng nhắc và nhanh chóng và đôi khi những người khác nhau sẽ không đồng ý liệu có nên là một tài sản hay một phương pháp hay không. Điều quan trọng chỉ là (tương đối) phù hợp với cách bạn làm điều đó (hoặc nhóm của bạn làm như thế nào).

Chúng có thể hoán đổi cho nhau nhưng một tín hiệu đặc tính cho người dùng rằng việc triển khai tương đối "đơn giản". Oh và cú pháp là một chút sạch hơn. Nói chung, triết lý của tôi là nếu bạn bắt đầu viết một tên phương thức bắt đầu bằng get hoặc set và lấy 0 hoặc một tham số (tương ứng) thì đó là một ứng cử viên chính cho một thuộc tính.

+0

Tôi nghĩ rằng đây nên là câu trả lời được chấp nhận. –

+0

Được bỏ phiếu. Điều này LAF không đúng. Sự phức tạp của một getter hoặc setter được đóng gói trong mã getter/setter. Làm thế nào phức tạp nó không phải là có liên quan ở tất cả, cũng không phải là nếu nó "ảnh hưởng đến một số thành viên dữ liệu" Đó là sự thật rằng không chuẩn hoặc nhiều tham số sẽ yêu cầu một phương pháp, nhưng nếu không câu trả lời này là không chính xác. – Hal50000

+0

Câu đầu tiên giải thích tất cả. Bravo. – SWIIWII

3

Tôi muốn sử dụng các thuộc tính cho các phương thức thêm/đặt với tham số . Nếu tham số là nhiều hơn, sử dụng phương pháp.

3

Thuộc tính chỉ nên được đặt đơn giản và nhận một lớp lót. Bất cứ điều gì nhiều hơn và nó thực sự nên được chuyển đến một phương pháp. Mã phức phải luôn có trong phương thức.

12

Nếu bạn đang đặt thuộc tính thực tế của đối tượng thì bạn sử dụng thuộc tính.

Nếu bạn đang thực hiện tác vụ/chức năng thì bạn sử dụng một phương pháp.

Trong ví dụ của bạn, đó là thuộc tính xác định được đặt.

Nếu tuy nhiên, chức năng của bạn là AppendToLabel thì bạn sẽ sử dụng một phương pháp.

2

Thuộc tính rất đẹp vì chúng có thể truy cập được trong trình thiết kế trực quan của studio trực quan, miễn là chúng có quyền truy cập.

Sử dụng chúng được sử dụng là bạn chỉ đang thiết lập và nhận và có lẽ một số xác thực không truy cập được một số lượng đáng kể mã. Hãy cẩn thận vì việc tạo các đối tượng phức tạp trong quá trình xác nhận không đơn giản.

Bất kỳ phương pháp nào khác là cách ưu tiên.

Nó không chỉ là về ngữ nghĩa. Sử dụng các thuộc tính không phù hợp bắt đầu có sự kỳ quặc xảy ra trong nhà thiết kế trực quan studio trực quan.

Ví dụ: tôi đã nhận được giá trị cấu hình trong thuộc tính của một lớp. Lớp cấu hình thực sự mở một tệp và chạy một truy vấn sql để lấy giá trị của cấu hình đó. Điều này gây ra các vấn đề trong ứng dụng của tôi, nơi tập tin cấu hình sẽ được mở và khóa bởi chính Visual Studio chứ không phải ứng dụng của tôi vì không chỉ đọc mà còn ghi giá trị cấu hình (thông qua phương thức setter). Để khắc phục điều này, tôi chỉ phải thay đổi nó thành một phương pháp.

3

Tôi chỉ sử dụng các thuộc tính để truy cập biến, tức là nhận và đặt các biến riêng lẻ hoặc nhận và đặt dữ liệu trong kiểm soát. Ngay sau khi bất kỳ loại thao tác dữ liệu nào là cần thiết/được thực hiện, tôi sử dụng các phương thức.

7

Bạn chỉ cần xem tên rất ... "Thuộc tính". Nó có nghĩa là gì? Từ điển định nghĩa nó theo nhiều cách, nhưng trong trường hợp này "một thuộc tính thiết yếu hoặc khác biệt hoặc chất lượng của một vật" phù hợp nhất.

Suy nghĩ về mục đích của hành động. Bạn có, trên thực tế, thay đổi hoặc lấy "một thuộc tính thiết yếu hoặc đặc biệt"? Trong ví dụ của bạn, bạn đang sử dụng một hàm để đặt thuộc tính của hộp văn bản. Điều đó có vẻ ngớ ngẩn, phải không?

Thuộc tính thực sự là các hàm. Tất cả đều biên dịch để nhận đượcXXX() và đặtXXX(). Nó chỉ giấu chúng trong đường cú pháp, nhưng đó là đường cung cấp một ý nghĩa ngữ nghĩa cho quá trình.

Suy nghĩ về các thuộc tính như thuộc tính. Một chiếc xe có nhiều thuộc tính. Màu sắc, MPG, Mẫu, v.v. Không phải tất cả các thuộc tính đều có thể đặt được, một số thuộc tính có thể tính toán được.

Trong khi đó, Phương thức là một hành động. GetColor phải là tài sản. GetFile() phải là một hàm. Một nguyên tắc khác là, nếu nó không thay đổi trạng thái của đối tượng, thì nó phải là một hàm. Ví dụ, CalculatePiToNthDigit (n) phải là một hàm, vì nó không thực sự thay đổi trạng thái của đối tượng Math mà nó gắn vào.

Điều này có thể hơi rambling một chút, nhưng nó thực sự sôi xuống để quyết định những gì các đối tượng của bạn, và những gì họ đại diện. Nếu bạn không thể tìm ra nếu nó phải là một tài sản hoặc chức năng, có lẽ nó không quan trọng đó.

8

Thuộc tính symantically là thuộc tính của đối tượng của bạn. Phương pháp là hành vi của đối tượng của bạn.

Nhãn là thuộc tính và có ý nghĩa hơn khi biến nó thành thuộc tính.

Về mặt lập trình hướng đối tượng, bạn nên có hiểu biết rõ ràng về những gì là một phần của hành vi và những gì chỉ là một thuộc tính.

Car {Màu, Model, Nhãn hiệu}

Một chiếc xe có màu, Người mẫu và do đó thuộc tính thương hiệu nó không có ý nghĩa để có một setcolor phương pháp hoặc SetModel vì symantically chúng tôi không hỏi xe để thiết lập màu sắc của riêng mình .

Vì vậy, nếu bạn ánh xạ trường hợp thuộc tính/phương thức cho đối tượng thực tế hoặc nhìn vào nó từ điểm quan sát, thì sự nhầm lẫn của bạn sẽ biến mất.

+0

'Thuộc tính symantically là thuộc tính của đối tượng của bạn. Phương pháp là hành vi của đối tượng của bạn.' giải thích thực sự tốt đẹp. Những lời giải thích ban đầu này xứng đáng hơn nhiều so với các báo giá được dán/ –

12

Thuộc tính là cách để tiêm hoặc truy xuất dữ liệu từ một đối tượng. Chúng tạo ra một trừu tượng hơn các biến hoặc dữ liệu trong một lớp. Chúng tương tự như getters và setters trong Java.

Phương pháp đóng gói một hoạt động.

Nói chung tôi sử dụng các thuộc tính để hiển thị các bit dữ liệu duy nhất hoặc các phép tính nhỏ trên một lớp, như thuế bán hàng. Mà có nguồn gốc từ số lượng các mặt hàng và chi phí của họ trong một giỏ mua hàng.

Tôi sử dụng các phương pháp khi tôi tạo một thao tác, như truy xuất dữ liệu từ cơ sở dữ liệu. Bất kỳ hoạt động nào có bộ phận chuyển động, là một ứng cử viên cho một phương pháp.

Trong ví dụ mã của bạn tôi sẽ bọc nó trong một tài sản nếu tôi cần phải truy cập vào nó bên ngoài nó chứa lớp:

public Label Title 
{ 
    get{ return titleLabel;} 
    set{ titleLabel = value;} 
} 

Thiết lập văn bản:

Title.Text = "Properties vs Methods"; 

Nếu tôi chỉ được thiết lập Thuộc tính văn bản của Nhãn này là cách tôi sẽ thực hiện:

public string Title 
{ 
    get{ return titleLabel.Text;} 
    set{ titleLabel.Text = value;} 
} 

Đặt văn bản:

Title = "Properties vs Methods"; 
2

Thuộc tính thiết kế Thuộc tính Dữ liệu hoặc thuộc tính của đối tượng lớp, Trong khi phương pháp là hành động hoặc hành vi của đối tượng lớp.

Trong Net, thế giới có ý nghĩa khác của việc sử dụng Thuộc tính:

  • Thuộc tính được sử dụng trong Databinding, trong khi get_/phương pháp set_ thì không.
  • Thuộc tính người dùng tuần tự hóa XML là cơ chế tự nhiên của sự serilization.
  • Thuộc tính được truy cập bởi PropertyGrid kiểm soát và thực tập ICustomTypeDescriptor, có thể được sử dụng hiệu quả nếu bạn đang viết thư viện tùy chỉnh.
  • Thuộc tính được kiểm soát bởi Attributes, người ta có thể sử dụng nó một cách khôn ngoan để thiết kế các phần mềm định hướng Aspect.

quan niệm sai lầm (IMHO) về Properties' sử dụng:

  • Được sử dụng để phơi bày tính toán nhỏ: ControlDesigner.SelectionRules 's được khối chạy vào 72 dòng !!
  • Được sử dụng để hiển thị cấu trúc dữ liệu bên trong: Ngay cả khi thuộc tính không ánh xạ tới thành viên dữ liệu nội bộ, một thuộc tính có thể sử dụng làm thuộc tính, nếu thuộc tính của lớp. Ngược lại, ngay cả khi thuộc tính của thuộc tính lớp của bạn không được khuyến khích, để trả về mảng giống như các thành viên dữ liệu (thay vào đó các phương thức được sử dụng để trả về bản sao sâu của các thành viên.)

Trong ví dụ ở đây nó có thể đã được viết, với ý nghĩa kinh doanh hơn như:

public String Title 
{ 
    set { Label.Text = text; } 
} 
7

Tìm kiếm thông qua MSDN, tôi tìm thấy một tài liệu tham khảo trên Properties vs Methods cung cấp một số hướng dẫn tuyệt vời để tạo các phương pháp:

  • Thao tác là chuyển đổi, chẳng hạn như Object.ToString.
  • Hoạt động này đủ tốn kém mà bạn muốn liên lạc với người dùng rằng họ nên xem xét lưu vào bộ nhớ cache kết quả.
  • Lấy giá trị thuộc tính bằng cách sử dụng trình truy cập nhận được sẽ có tác dụng phụ quan sát .
  • Gọi thành viên hai lần liên tiếp tạo ra các kết quả khác nhau.
  • Thứ tự thực hiện là quan trọng. Lưu ý rằng các thuộc tính của loại phải là có thể được đặt và truy lục trong bất kỳ thứ tự nào.
  • Thành viên tĩnh nhưng trả về một giá trị có thể thay đổi.
  • Thành viên trả về một mảng. Các thuộc tính trả về mảng có thể là rất gây hiểu lầm. Thông thường, nó là cần thiết để trả lại bản sao của mảng nội bộ để người dùng không thể thay đổi trạng thái nội bộ. Điều này, cùng với với thực tế là người dùng có thể dễ dàng giả sử đây là thuộc tính được lập chỉ mục, dẫn đến mã không hiệu quả.
+0

hoàn toàn có ý nghĩa, cảm ơn ... – Marko

-1

Tôi đến từ java tôi đã sử dụng get .. set .. phương pháp trong một thời gian.

Khi tôi viết mã, tôi không tự hỏi mình: "truy cập dữ liệu này rất đơn giản hoặc yêu cầu một quá trình nặng?" bởi vì mọi thứ có thể thay đổi (ngày nay chiếm đoạt tài sản này là đơn giản, tomonrow có thể yêu cầu một số hoặc quá trình nặng).

Hôm nay tôi có một phương pháp SetAge (int age) tomonrow tôi cũng sẽ có phương thức SetAge (ngày sinh) để tính tuổi bằng cách sử dụng ngày sinh.

Tôi đã rất thất vọng khi thuộc tính biến đổi trình biên dịch nhận và đặt nhưng không xem xét các phương thức Get ... và Set .. của tôi giống nhau.

-1

Đây là một bộ tốt của hướng dẫn khi sử dụng tính vs phương pháp từ Bill Wagner

  • Sử dụng một tài sản khi tất cả đều là sự thật: Các getters nên đơn giản và do đó khó có thể ném ngoại lệ. Lưu ý rằng điều này ngụ ý không có quyền truy cập mạng (hoặc cơ sở dữ liệu). Hoặc có thể thất bại, và do đó sẽ ném một ngoại lệ.
  • Chúng không nên có sự phụ thuộc lẫn nhau. Lưu ý rằng điều này sẽ bao gồm thiết lập một thuộc tính và có ảnh hưởng đến một thuộc tính khác.(Ví dụ, thiết lập thuộc tính FirstName sẽ ảnh hưởng đến thuộc tính FullName chỉ đọc mà bao gồm tên đầu tiên + thuộc tính tên cuối cùng ngụ ý một phụ thuộc như vậy)
  • Chúng phải được đặt theo thứ tự bất kỳ
  • Bộ khởi động không có quan sát được tác dụng phụ Lưu ý rằng hướng dẫn này không loại trừ một số hình thức đánh giá lười biếng trong một tài sản.
  • Phương pháp phải luôn trả lại ngay lập tức. (Lưu ý rằng điều này ngăn cản một thuộc tính thực hiện cuộc gọi truy cập cơ sở dữ liệu, cuộc gọi dịch vụ web hoặc hoạt động tương tự khác).
  • Sử dụng phương thức nếu thành viên trả về một mảng.
  • Các cuộc gọi lặp lại tới bộ thu phát (không có mã can thiệp) phải trả lại cùng một giá trị.
  • Các cuộc gọi lặp lại tới trình thiết lập (có cùng giá trị) sẽ không tạo ra sự khác biệt so với một cuộc gọi.

  • Không được trả về tham chiếu đến cấu trúc dữ liệu nội bộ (Xem mục 23). Một phương thức có thể trả về một bản sao sâu và có thể tránh được vấn đề này.

* Trích từ câu trả lời của tôi cho câu hỏi trùng lặp.

+0

Được đánh giá cao nhất & được chấp nhận ở đây http://stackoverflow.com/a/1294189/1551 Tại sao lại là downvote? –

+0

Tôi nhận ra rằng tôi hơi muộn với bữa tiệc, nhưng sự sụt giảm đó rất có thể xảy ra do thực tế là bạn đã sao chép câu trả lời của mình. Bằng cách sao chép, bạn thừa nhận rằng câu hỏi này về cơ bản là bản sao của câu hỏi khác. Như vậy, bạn nên gắn cờ nó là bản sao thay vì trả lời nó. Tôi khuyên bạn nên xem [một bài viết trên Meta] (https://meta.stackexchange.com/questions/10841/how-should-duplicate-questions-be-handled/) để biết cách xử lý các câu hỏi trùng lặp. –

3

Ngoài ra lớn cộng với thuộc tính là giá trị của tài sản có thể được nhìn thấy trong Visual Studio trong quá trình gỡ lỗi.

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