Thứ tự các mục trong các lớp: Trường, Thuộc tính, Trình xây dựng, Phương thức


637

Có hướng dẫn chính thức về C # cho thứ tự các mặt hàng theo cấu trúc lớp không?

Nó có đi không

  • Lĩnh vực công cộng
  • Lĩnh vực tư nhân
  • Tính chất
  • Người xây dựng
  • Phương pháp
    nào?

Tôi tò mò liệu có một quy tắc cứng và nhanh về thứ tự của các mặt hàng không? Tôi là loại ở khắp mọi nơi. Tôi muốn gắn bó với một tiêu chuẩn cụ thể để tôi có thể làm điều đó ở mọi nơi.

Vấn đề thực sự là các thuộc tính phức tạp hơn của tôi cuối cùng trông rất giống các phương thức và chúng cảm thấy lạc lõng ở phía trên trước khi xây dựng.

Bất kỳ lời khuyên / đề nghị?


7
Trên thực tế, để trả lời câu hỏi thực tế, không, không có hướng dẫn chính thức. StyleCop thực hiện các hướng dẫn được phát triển để sử dụng trong một nhóm cụ thể trong Microsoft. Đây không phải là hướng dẫn chính thức và thậm chí có thể không thống nhất giữa các nhóm trong Microsoft.
John Saunders

2
Một mẹo đơn giản là xem siêu dữ liệu của một số lớp phức tạp trong .net (F12 trong VS). Bạn sẽ biết làm thế nào nó ra lệnh ít nhất cho các thành viên publicprotected.
nawfal

19
Câu hỏi này không dựa trên ý kiến, vì nó hỏi liệu có hướng dẫn chính thức hay không. Có hướng dẫn hoặc không có!
Simon MᶜKenzie

2
@nawfal Tôi nhận ra đây là một nhận xét cũ, tôi thích thủ thuật mà bạn đã đề cập, nhưng đáng nói là nó sẽ không hiển thị privatehoặc internalcác thành viên (tôi tin). Cách tốt đẹp để xem publicprotected, tuy nhiên. Chúng ta có thể thấy nguồn gốc của các lớp .NET Framework, đây referencesource.microsoft.com quá
Adam Plocher

Câu trả lời:


950

Theo Tài liệu quy tắc StyleCop, việc đặt hàng như sau.

Trong một lớp, cấu trúc hoặc giao diện: (SA1201 và SA1203)

  • Trường không đổi
  • Lĩnh vực
  • Người xây dựng
  • Người hoàn thiện (Kẻ hủy diệt)
  • Đại biểu
  • Sự kiện
  • Enums
  • Giao diện ( triển khai giao diện )
  • Tính chất
  • Người lập chỉ mục
  • Phương pháp
  • Cấu trúc
  • Các lớp học

Trong mỗi nhóm này, thứ tự truy cập: (SA1202)

  • công cộng
  • nội bộ
  • bảo vệ nội bộ
  • bảo vệ
  • riêng tư

Trong mỗi nhóm truy cập, sắp xếp theo thứ tự tĩnh, sau đó không tĩnh: (SA1204)

  • tĩnh
  • không tĩnh

Trong mỗi nhóm trường tĩnh / không tĩnh, sắp xếp theo thứ tự chỉ đọc, sau đó không chỉ đọc: (SA1214 và SA1215)

  • chỉ đọc
  • không đọc

Một danh sách không được kiểm soát dài 130 dòng, vì vậy tôi sẽ không hủy đăng ký ở đây. Các phương thức không được kiểm soát là:

  • phương pháp tĩnh công cộng
  • phương pháp công cộng
  • phương pháp tĩnh bên trong
  • phương pháp nội bộ
  • phương pháp tĩnh bên trong được bảo vệ
  • phương pháp nội bộ được bảo vệ
  • phương pháp tĩnh được bảo vệ
  • phương pháp bảo vệ
  • phương pháp tĩnh riêng
  • phương pháp riêng tư

Tài liệu lưu ý rằng nếu thứ tự quy định không phù hợp - giả sử, nhiều giao diện đang được triển khai và các phương thức và thuộc tính giao diện nên được nhóm lại với nhau - sau đó sử dụng một lớp một phần để nhóm các phương thức và thuộc tính liên quan lại với nhau.


31
Tôi muốn cảm ơn bạn đã nỗ lực trong bài viết này. Tôi đang cố gắng biến công cụ StyleCop thành một tiêu chuẩn (ngay cả khi chỉ để nhất quán và giúp bạn dễ dàng tìm thấy mọi thứ) và điều này rất có giá trị.
Kenny Mann

47
Cá nhân, tôi thấy việc đặt hàng các phương thức tĩnh gây phiền nhiễu. Tôi có thể thấy đối số cho các phương thức công khai tĩnh xuất hiện trước, nhưng tôi thường muốn các phương thức tĩnh riêng sau các thành viên. Chúng là những tiện ích sau tất cả.
Jonathan Wright

18
Tôi thích mẹo lớp một phần
Keith Sirmons

10
Chỉ cần một lưu ý về các lớp học một phần. Vì trong thời gian biên dịch, tất cả các phần được biên dịch thành một loại duy nhất, tôi sẽ luôn cố gắng đảm bảo một lý do chính đáng để tạo ra chi phí bổ sung đó. Lý do chính cho các lớp một phần là để mở rộng mã nguồn tự động hoặc khi làm việc trên các dự án lớn để cho phép nhiều nhà phát triển làm việc trên cùng một lớp nhưng các tệp riêng biệt.
Không có

4
@ FrançoisWahl Có phải chi phí liên kết với trình biên dịch kết hợp các lớp một phần thành một loại lớn không?
dav_i

38

Thay vì nhóm theo khả năng hiển thị hoặc theo loại mặt hàng (trường, thuộc tính, phương thức, v.v.), làm thế nào về nhóm theo chức năng?


3
Nếu "sắp xếp" bằng các khuyến nghị của StyleCop thì đó là một loại chức năng. Có một lý do chính đáng tại sao một số phương pháp là công khai và những phương pháp khác là riêng tư. Mã này thực sự dễ đọc hơn: Nếu mở tệp .cs của lớp, tôi thấy ngay các phương thức công khai "quan trọng" hơn các phương thức riêng tư (đối với anh chàng đang sử dụng lớp đó)
hfrmobile

75
Nếu bạn có quá nhiều phương thức, thuộc tính, v.v. trong lớp mà bạn cần nhóm chúng theo từng phần, có thể đó là dấu hiệu cho thấy lớp đang làm quá nhiều?
Ryan Lundy

10
Ngay cả khi lớp học nhỏ, sẽ không có ý nghĩa khi nhóm các phương thức công khai với các phương thức riêng tương ứng của chúng mà chỉ được gọi bằng phương thức công khai này?
Markus Meyer

11
+1 nếu phương thức công khai Foo () gọi InternalFoo () được bảo vệ / riêng tư, thì phương thức thứ hai đó tốt hơn ngay bên dưới DoFoo () trong nguồn, không nằm sâu trong số các phương thức được bảo vệ / riêng tư khác.
Anders Forsgren

60
Nhóm theo chức năng được gọi là một lớp
MrDosu

26

Đây là một câu hỏi cũ nhưng vẫn rất phù hợp, vì vậy tôi sẽ thêm câu hỏi này: Điều đầu tiên bạn tìm kiếm khi mở tệp lớp mà bạn có thể hoặc chưa từng đọc trước đây là gì? Lĩnh vực? Tính chất? Tôi đã nhận ra từ kinh nghiệm rằng hầu như tôi luôn đi săn các nhà xây dựng, bởi vì điều cơ bản nhất để hiểu là cách vật thể này được xây dựng.

Do đó, tôi đã bắt đầu đặt các nhà xây dựng lên hàng đầu trong các tệp lớp và kết quả rất tốt về mặt tâm lý. Các khuyến nghị tiêu chuẩn của việc đặt các nhà xây dựng sau một loạt các điều khác cảm thấy không phù hợp.

Tính năng hàm tạo chính sắp tới trong C # 6 cung cấp bằng chứng cho thấy vị trí tự nhiên của hàm tạo nằm ở trên cùng của lớp - trên thực tế các hàm tạo chính được chỉ định ngay cả trước dấu ngoặc mở.

Thật buồn cười khi một sự khác biệt sắp xếp lại như thế này. Nó nhắc nhở tôi về cách các usingcâu lệnh được sử dụng để sắp xếp thứ tự - với không gian tên Hệ thống trước tiên. Lệnh "Organize Usings" của Visual Studio đã sử dụng thứ tự này. Bây giờ usings chỉ được sắp xếp theo thứ tự abc, không có xử lý đặc biệt cho không gian tên hệ thống. Kết quả chỉ cảm thấy đơn giản và sạch sẽ hơn.


2
Theo tôi, việc khởi tạo / xây dựng lớp là phức tạp. Các trường được khởi tạo trước khi các hàm tạo rõ ràng được chạy, do đó, đi sâu hơn vào đối số của bạn về cơ bản đưa các thành viên theo thứ tự chúng được sử dụng / tạo, các trường khởi tạo sẽ được đặt trước các hàm tạo được khai báo rõ ràng. Các trường tĩnh khởi tạo và các hàm tạo tĩnh làm cho nó thậm chí còn thú vị hơn.
David Culp

1
Trên thực tế, thứ tự mà họ có xu hướng tìm kiếm bởi con người, khái niệm lập trình văn học mà mã đầu tiên phải được con người đọc được.
sáng

1
Lưu ý rằng các nhà xây dựng chính đã bị xóa khỏi các kế hoạch cho C # 6: stackoverflow.com/a/26915809/5085211
fuglede

4
9 trong số 10 lần, tôi đang tìm kiếm giao diện công cộng, đó là lý do tại sao tôi đặt tất cả các thành viên công khai lên trước, tiếp theo là nội bộ, tiếp theo là bảo vệ và cuối cùng là các thành viên tư nhân.
Matt Davis

15

Tôi không biết về ngôn ngữ hoặc tiêu chuẩn ngành, nhưng tôi có xu hướng sắp xếp mọi thứ theo thứ tự này với mỗi phần được gói trong một #region:

sử dụng Tuyên bố

Không gian tên

Lớp học

Thành viên tư nhân

Tài sản công cộng

Người xây dựng

Phương pháp công cộng

Phương pháp riêng tư


Đây chính xác là cách tôi làm nó là tốt. Ngoại trừ giữa Thành viên Lớp và Thành viên tư nhân, tôi có bất kỳ Hằng và Công khai nào, v.v.
deegee

Có, tôi thích giữ tài sản công cộng sau các phương pháp riêng tư. Những người khác thích đặt hàm tạo trước các thuộc tính công cộng ... nhưng trong đầu tôi thích có các giá trị / hàm tạo / hành vi theo thứ tự đó. Sau đó, "giá trị" được chia thành hằng số / privateMembers / property và như vậy. Thông thường tôi không sử dụng các vùng, ngoại trừ một số mô hình chế độ xem lớn ... tốt, chế độ xem WPF là loại đặc biệt và trong trường hợp này tôi thường đặt các trường riêng tư sao lưu trước mỗi tài sản công cộng. Trong trường hợp này, tập hợp trường riêng cộng với thành viên là cùng một đơn vị
zameb

15

Tôi sẽ khuyên bạn nên sử dụng các tiêu chuẩn mã hóa từ IDesign hoặc các tiêu chuẩn được liệt kê trên trang web của Brad Abram . Đó là hai cái tốt nhất mà tôi đã tìm thấy.

Brad sẽ nói ...

Thành viên của lớp nên được sắp xếp theo thứ tự và được nhóm thành các phần (Trường, Trình xây dựng, Thuộc tính, Sự kiện, Phương thức, Triển khai giao diện riêng, Các kiểu lồng nhau)


3
Liên kết đó dường như chỉ dẫn đến trang chủ IDesign những ngày này. Dường như các tiêu chuẩn mã hóa được ẩn đằng sau một liên kết tải xuống được gửi qua email trong những ngày này #justaying
Liam

Hướng dẫn nên có lý do. Lý do cho điều đó là: 1. để bạn hiểu, 2. để bạn có thể áp dụng phán đoán về các trường hợp biên giới, tinh vi, mơ hồ, không lường trước hoặc xung đột, 3. để bạn có thể điều chỉnh khi điều kiện thay đổi và một số hướng dẫn không còn áp dụng.
Pablo H

6

Như đã đề cập trước đây, không có gì trong ngôn ngữ C # chỉ ra bố cục, cá nhân tôi sử dụng các vùng và tôi làm một cái gì đó như thế này cho một lớp trung bình.

public class myClass
{
#region Private Members

#endregion
#region Public Properties

#endregion

#region Constructors

#endregion
#region Public Methods

#endregion
}

Dù sao nó cũng có ý nghĩa với tôi


19
Ở đây có thể nói (chỉ để biết thông tin) rằng stylecop không khuyến nghị không sử dụng các vùng (SA1124 DoNotUseRegions)
Gerwald


1
@zwcloud Chắc chắn, trong một tệp có 5538 dòng, các vùng là cần thiết, nhưng điều đó không có nghĩa là bạn nên sử dụng các vùng trong các tệp bình thường.
Ghost4Man

1
@Gerwald: Tôi nghĩ StyleCop chỉ dành cho những người sử dụng StyleCop. Đây là một trong nhiều tiêu chuẩn
zameb 7/12/18

1
@zameb: Tôi muốn nói, các quy tắc StyleCop là một trong những nguyên tắc mã hóa phổ biến nhất cho C #. Khi viết mã bằng bất kỳ ngôn ngữ nào, tôi luôn cố gắng tìm ra bộ hướng dẫn mã hóa phổ biến nhất và tuân theo chúng.
Gerwald

5

Từ StyleCop

lĩnh vực riêng tư, lĩnh vực công cộng, nhà xây dựng, thuộc tính, phương thức công cộng, phương thức riêng tư

Vì StyleCop là một phần của quy trình xây dựng MS, bạn có thể xem đó là một tiêu chuẩn thực tế


Hấp dẫn. Bạn có sử dụng StyleCop thường xuyên không?
mmcdole

Đối với một dự án có, bởi vì nó được sử dụng cho một số hợp đồng MS hoạt động ngay bây giờ. Nụ cười
blowdart

1
Sử dụng StyleCop trong một thời gian dài và nếu sử dụng các khuyến nghị đó làm cho mã thực sự dễ đọc hơn: Nếu mở tệp .cs của lớp, tôi thấy ngay các phương thức công khai "quan trọng" hơn các phương thức riêng tư. Công chúng là "giao diện" của lớp những gì nó cung cấp và những gì có thể được kiểm tra (thích TDD và Test-First)
hfrmobile

1
Theo các trường công khai StyleCop nên đi trước các trường riêng stylecop.com/docs/SA1202.html
Michael Freidgeim

1
Ý của bạn là "StyleCop là một phần của quá trình xây dựng MS"? Microsoft có sử dụng StyleCop cho tất cả mã của nó không?
Rico Suter

5

Thông thường tôi cố gắng làm theo mô hình tiếp theo:

  • thành viên tĩnh (thường có bối cảnh khác, phải an toàn cho chuỗi, v.v.)
  • thành viên thể hiện

Mỗi phần (tĩnh và thể hiện) bao gồm các loại thành viên sau:

  • toán tử (luôn luôn tĩnh)
  • các trường (khởi tạo trước khi xây dựng)
  • nhà xây dựng
  • hàm hủy ( là một truyền thống để theo các nhà xây dựng )
  • tính chất
  • phương pháp
  • sự kiện

Sau đó, các thành viên được sắp xếp theo mức độ hiển thị (từ ít đến dễ thấy hơn):

  • riêng tư
  • nội bộ
  • bảo vệ nội bộ
  • bảo vệ
  • công cộng

Thứ tự không phải là một giáo điều: các lớp đơn giản dễ đọc hơn, tuy nhiên, các lớp phức tạp hơn cần nhóm theo ngữ cảnh cụ thể.


5

Sở thích của tôi là đặt hàng theo loại và sau đó giảm khả năng hiển thị như sau

public methods
public events
public properties

protected methods
protected events
protected properties

private methods
private events
private properties
private fields

public delegates
public interfaces
public classes
public structs

protected delegates
protected interfaces
protected classes
protected structs

private delegates
private interfaces
private classes
private structs

Tôi biết điều này vi phạm Style Cop và nếu ai đó có thể cho tôi một lý do chính đáng tại sao tôi nên đặt chi tiết triển khai của một loại trước giao diện của nó, tôi sẵn sàng thay đổi. Hiện tại, tôi có một ưu tiên mạnh mẽ để đưa các thành viên tư nhân cuối cùng.

Lưu ý: Tôi không sử dụng các lĩnh vực công cộng hoặc được bảo vệ.


3
Đã đồng ý. Tôi thực sự tự hỏi nếu khái niệm đặt các thành viên tư nhân lên hàng đầu không phải là sự nắm giữ từ những ngày C mà các biến phải được khai báo trước. Tôi hầu như luôn muốn nhìn thấy giao diện công cộng đầu tiên, không phải các lớp bên trong.
Matt Davis

1
Điều đó thực sự có rất nhiều ý nghĩa. Tôi cá rằng đó là một sự tiếp quản từ C.
Aluan Haddad

Một số gotcha lớn nhất có thể là thuộc tính IMO. Khi có logic trên getter / setter mà bạn không biết, điều đó sẽ có nhiều khả năng cắn sau đó tác dụng phụ trong các phương thức (mà bạn tự nhiên mong đợi chúng sẽ xuất hiện) Do đó, tôi thích các thuộc tính bên cạnh các trường của chúng ở trên cùng , vì vậy khi tôi nhìn vào một lớp học lần đầu tiên, tôi thấy đỉnh của Gotcha. Khi tôi đọc một phương thức, tôi thường điều hướng / nhảy ngay đến phương thức đó
Ryan The Leach


3

hướng dẫn mã hóa duy nhất mà tôi thấy được đề xuất cho việc này là đặt các trường ở đầu định nghĩa lớp.

tôi có xu hướng đặt các nhà xây dựng bên cạnh.

Nhận xét chung của tôi là bạn nên bám vào một lớp trên mỗi tệp và nếu lớp đó đủ lớn để tổ chức các thuộc tính so với các phương thức là mối quan tâm lớn, thì lớp đó lớn đến mức nào và bạn có nên tái cấu trúc nó không? nó đại diện cho nhiều mối quan tâm?


3
và một khi bạn cần các khu vực ... bạn đã mất.
Hamish Smith

3

Tôi thích đặt các trường riêng lên trên cùng cùng với (các) hàm tạo, sau đó đặt các bit giao diện công cộng sau đó, sau đó là các bit giao diện riêng.

Ngoài ra, nếu định nghĩa lớp của bạn đủ dài để việc sắp xếp các mục trở nên quan trọng, thì đó có lẽ là mùi mã cho thấy lớp của bạn quá cồng kềnh và phức tạp và bạn nên cấu trúc lại.


3

Tôi giữ nó đơn giản nhất có thể (ít nhất là đối với tôi)

Khai báo
khai báo Trình
xây dựng
ghi đè
phương thức
Thuộc tính Trình xử
lý sự kiện


2

Chắc chắn không có gì trong ngôn ngữ thực thi nó theo bất kỳ cách nào. Tôi có xu hướng nhóm các thứ theo khả năng hiển thị (công khai, sau đó được bảo vệ, sau đó riêng tư) và sử dụng #regions để nhóm các thứ liên quan theo chức năng, bất kể đó là tài sản, phương thức hay bất cứ điều gì. Các phương pháp xây dựng (cho dù các công cụ thực tế hoặc các chức năng tĩnh của nhà máy) thường ở ngay trên đầu vì chúng là điều đầu tiên khách hàng cần biết.


Tôi cũng sử dụng các vùng để phân tách bằng khả năng hiển thị và việc bố trí mã Vùng được giữ cho tôi trung thực. rauchy.net/regionarters
Quên dấu chấm phẩy

Tôi không thấy vấn đề gì khi sử dụng #regions, tuy nhiên tôi thường thấy rằng ngay khi tôi muốn đưa vào một khu vực, điều đó nhắc tôi xem xét việc chia lớp của mình.
mikecamimo

2

Tôi biết điều này là cũ nhưng thứ tự của tôi là như sau:

theo thứ tự công cộng, được bảo vệ, riêng tư, nội bộ, trừu tượng

  • Hằng số
  • Biến tĩnh
  • Lĩnh vực
  • Sự kiện
  • Người xây dựng
  • Phương pháp
  • Tính chất
  • Đại biểu

Tôi cũng thích viết ra các thuộc tính như thế này (thay vì cách tiếp cận tốc ký)

// Some where in the fields section
private int someVariable;

// I also refrain from
// declaring variables outside of the constructor

// and some where in the properties section I do
public int SomeVariable
{
    get { return someVariable; }
    set { someVariable = value; }
}
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.