Urutan item dalam kelas: Bidang, Properti, Konstruktor, Metode


637

Apakah ada pedoman C # resmi untuk urutan item dalam hal struktur kelas?

Apakah itu pergi:

  • Bidang Publik
  • Bidang Pribadi
  • Properti
  • Konstruktor
  • Metode
    ?

Saya ingin tahu apakah ada aturan yang keras dan cepat tentang urutan barang? Aku agak di semua tempat. Saya ingin tetap dengan standar tertentu sehingga saya bisa melakukannya di mana saja.

Masalah sebenarnya adalah properti saya yang lebih kompleks akhirnya tampak sangat mirip metode dan mereka merasa tidak pada tempatnya di atas sebelum konstruktor.

Ada tips / saran?


7
Sebenarnya, untuk menjawab pertanyaan yang sebenarnya, tidak, tidak ada pedoman resmi. StyleCop mengimplementasikan pedoman yang dikembangkan untuk digunakan dalam satu grup tertentu di Microsoft. Ini bukan pedoman resmi, dan bahkan mungkin tidak seragam di antara kelompok-kelompok di Microsoft.
John Saunders

2
Salah satu trik mudah adalah dengan melihat metadata dari beberapa kelas kompleks di .net (F12 dalam VS). Anda akan mengetahui bagaimana dipesan setidaknya untuk publicdan protectedanggota.
nawfal

19
Pertanyaan ini bukan berdasarkan opini, karena menanyakan apakah ada pedoman resmi. Entah ada pedoman atau tidak!
Simon MᶜKenzie

2
@nawfal Saya menyadari ini adalah komentar lama, saya suka trik yang Anda sebutkan, tetapi perlu disebutkan bahwa itu tidak akan ditampilkan privateatau internalanggota (saya percaya). Cara melihat yang bagus publicdan protected, bagaimanapun. Kita dapat melihat sumber dari kelas .NET Framework, di sini referenceource.microsoft.com juga
Adam Plocher

Jawaban:


951

Menurut Dokumentasi Aturan StyleCop pemesanan adalah sebagai berikut.

Di dalam kelas, struct atau antarmuka: (SA1201 dan SA1203)

  • Bidang Konstan
  • Bidang
  • Konstruktor
  • Finalizers (Destructors)
  • Delegasi
  • Acara
  • Enum
  • Antarmuka ( implementasi antarmuka )
  • Properti
  • Pengindeks
  • Metode
  • Structs
  • Kelas

Dalam masing-masing kelompok ini pesan melalui akses: (SA1202)

  • publik
  • intern
  • internal terlindungi
  • terlindung
  • pribadi

Di dalam masing-masing grup akses, pesan dengan statis, kemudian non-statis: (SA1204)

  • statis
  • tidak statis

Dalam masing-masing grup bidang statis / non-statis, pesan dengan hanya-baca, kemudian tidak-baca: (SA1214 dan SA1215)

  • dibaca saja
  • tidak dibaca

Daftar yang belum dibuka adalah 130 baris, jadi saya tidak akan membuka gulungannya di sini. Bagian metode yang belum dibuka adalah:

  • metode statis publik
  • metode publik
  • metode statis internal
  • metode internal
  • metode statis internal yang dilindungi
  • metode internal yang dilindungi
  • metode statis terlindungi
  • metode yang dilindungi
  • metode statis pribadi
  • metode pribadi

Dokumentasi mencatat bahwa jika urutan yang ditentukan tidak sesuai - katakanlah, banyak antarmuka sedang dilaksanakan, dan metode dan properti antarmuka harus dikelompokkan bersama - kemudian gunakan kelas parsial untuk mengelompokkan metode dan properti terkait bersama-sama.


31
Saya ingin mengucapkan terima kasih karena telah melakukan upaya dalam posting ini. Saya mencoba menjadikan barang-barang StyleCop sebagai standar (walaupun hanya untuk menjadi konsisten dan membuatnya mudah untuk menemukan sesuatu) dan ini sangat berharga.
Kenny Mann

47
Secara pribadi, saya menemukan urutan metode statis mengganggu. Saya dapat melihat argumen untuk metode publik statis yang lebih dulu, tetapi saya biasanya menginginkan metode statis pribadi setelah anggota. Bagaimanapun, itu utilitas.
Jonathan Wright

18
Saya menyukai tip kelas parsial
Keith Sirmons

10
Hanya catatan tentang kelas parsial. Mengingat bahwa selama waktu kompilasi semua parsial dikompilasi menjadi satu jenis, saya akan selalu berusaha memastikan alasan yang baik untuk membuat overhead tambahan itu. Alasan utama untuk kelas parsial adalah untuk memperpanjang kode sumber penghasil otomatis atau ketika bekerja pada proyek besar untuk memungkinkan beberapa pengembang bekerja pada kelas yang sama tetapi memisahkan file.
Tidak

4
@ FrançoisWahl Apakah overhead terkait dengan kompiler menggabungkan kelas parsial menjadi satu jenis yang besar?
dav_i

38

Daripada mengelompokkan berdasarkan visibilitas atau berdasarkan jenis item (bidang, properti, metode, dll.), Bagaimana dengan pengelompokan berdasarkan fungsionalitas?


3
Jika "mengurutkan" menggunakan rekomendasi StyleCop itu adalah semacam fungsi. Ada alasan bagus mengapa beberapa metode bersifat publik dan lainnya bersifat pribadi. Kode ini benar-benar lebih baik dibaca: Jika membuka file .cs kelas saya segera melihat metode publik yang "lebih penting" daripada yang pribadi (untuk pria yang menggunakan kelas itu)
hfrmobile

75
Jika Anda memiliki begitu banyak metode, properti, dll. Di kelas Anda sehingga Anda perlu mengelompokkannya berdasarkan bagian, mungkin itu pertanda bahwa kelas terlalu banyak melakukan?
Ryan Lundy

10
Sekalipun kelasnya kecil, tidakkah masuk akal untuk mengelompokkan metode publik dengan metode privat terkait yang hanya dipanggil dengan metode publik ini?
Markus Meyer

11
+1 jika metode publik Foo () memanggil InternalFoo () yang diproteksi / privat, maka metode kedua lebih baik berada tepat di bawah DoFoo () di sumbernya, tidak di suatu tempat lebih jauh di bawah di antara metode lain yang dilindungi / pribadi.
Anders Forsgren

60
pengelompokan berdasarkan fungsionalitas disebut kelas
MrDosu

26

Ini adalah pertanyaan lama tetapi masih sangat relevan, jadi saya akan menambahkan ini: Apa hal pertama yang Anda cari ketika Anda membuka file kelas yang mungkin Anda baca atau belum baca? Bidang? Properti? Saya telah menyadari dari pengalaman bahwa hampir selalu saya pergi berburu untuk konstruktor, karena hal yang paling mendasar untuk dipahami adalah bagaimana objek ini dibangun.

Oleh karena itu, saya mulai menempatkan konstruktor sebagai yang pertama di file kelas, dan hasilnya secara psikologis sangat positif. Rekomendasi standar menempatkan konstruktor setelah banyak hal lain terasa disonan.

Fitur konstruktor primer yang akan datang dalam C # 6 memberikan bukti bahwa tempat alami untuk konstruktor berada di bagian paling atas kelas - sebenarnya konstruktor primer ditentukan bahkan sebelum kurung buka.

Sangat lucu betapa banyak perbedaan penataan ulang seperti ini. Ini mengingatkan saya pada bagaimana usingpernyataan yang digunakan dipesan - dengan System namespaces terlebih dahulu. Perintah "Atur Penggunaan" Visual Studio menggunakan pesanan ini. Sekarang usinghanya dipesan secara alfabet, tanpa perlakuan khusus yang diberikan untuk ruang nama Sistem. Hasilnya hanya terasa lebih sederhana dan bersih.


2
Inisialisasi / konstruksi kelas, menurut saya, berbelit-belit. Field diinisialisasi sebelum konstruktor eksplisit dijalankan, jadi lanjutkan argumen Anda tentang menempatkan anggota pada urutan yang digunakan / dibuat, bidang yang diinisialisasi akan sebelum konstruktor yang dinyatakan secara eksplisit. Inisialisasi bidang statis dan konstruktor statis membuatnya semakin menarik.
David Culp

1
Sebenarnya, urutan mereka cenderung dicari oleh manusia, gagasan pemrograman sastra bahwa kode pertama-tama harus dapat dibaca oleh manusia.
cerah

1
Perhatikan bahwa konstruktor utama telah dihapus dari rencana untuk C # 6: stackoverflow.com/a/26915809/5085211
fuglede

4
9 kali dari 10, saya mencari antarmuka publik, itulah sebabnya saya mengutamakan semua anggota publik, diikuti oleh internal, diikuti oleh dilindungi, dan akhirnya oleh anggota pribadi.
Matt Davis

15

Saya tidak tahu tentang standar bahasa atau industri, tetapi saya cenderung untuk meletakkan berbagai hal dalam urutan ini dengan setiap bagian terbungkus dalam #region:

menggunakan Pernyataan

Namespace

Kelas

Anggota pribadi

Properti publik

Konstruktor

Metode publik

Metode pribadi


Ini persis bagaimana saya melakukannya juga. Kecuali antara Anggota Kelas dan Pribadi, saya memiliki Konstanta Publik dan
Enum

Ya, saya lebih suka menjaga properti publik setelah metode pribadi. Orang lain lebih suka menempatkan konstruktor di atas properti publik ... tetapi di kepala saya, saya lebih suka memiliki nilai / konstruktor / perilaku, dalam urutan itu. Kemudian "nilai" dibagi sebagai konstanta / privateMembers / properties dan sebagainya. Biasanya saya tidak menggunakan daerah, kecuali untuk beberapa model tampilan besar ... well, model tampilan WPF adalah jenis khusus, dan, dalam hal ini saya biasanya menempatkan bidang swasta dukungan sebelum setiap properti publik. Dalam hal ini, himpunan bidang pribadi ditambah anggota publik adalah unit yang sama
zameb

15

Saya akan merekomendasikan menggunakan standar pengkodean dari IDesign atau yang terdaftar di situs web Brad Abram . Itu adalah dua yang terbaik yang saya temukan.

Brad akan mengatakan ...

Anggota kelas harus diurutkan berdasarkan abjad, dan dikelompokkan menjadi beberapa bagian (Bidang, Konstruktor, Properti, Acara, Metode, implementasi antarmuka pribadi, tipe bersarang)


3
Tautan itu tampaknya mengarah ke halaman beranda IDesign hari ini. Tampaknya standar pengkodean tersembunyi di balik tautan unduh yang diemail hari ini #justsaying
Liam

Pedoman harus memiliki dasar pemikiran. Alasannya adalah: 1. agar Anda mengerti, 2. sehingga Anda dapat menerapkan penilaian pada kasus batas, halus, ambigu, tak terduga atau bertentangan, 3. sehingga Anda dapat menyesuaikan ketika kondisi berubah dan beberapa pedoman tidak lagi berlaku.
Pablo H

6

Seperti disebutkan sebelumnya tidak ada dalam bahasa C # yang menentukan tata letak, saya pribadi menggunakan daerah, dan saya melakukan sesuatu seperti ini untuk kelas rata-rata.

public class myClass
{
#region Private Members

#endregion
#region Public Properties

#endregion

#region Constructors

#endregion
#region Public Methods

#endregion
}

Masuk akal bagi saya juga


19
Ini untuk mengatakan (hanya untuk informasi) bahwa stylecop merekomendasikan tidak menggunakan daerah (SA1124 DoNotUseRegions)
Gerwald


1
@ zwcloud Tentu, dalam file dengan 5538 baris, region diperlukan, tetapi itu tidak berarti Anda harus menggunakan region dalam file normal.
Ghost4Man

1
@ Gerwald: Saya pikir StyleCop hanya untuk orang yang menggunakan StyleCop. Ini adalah salah satu dari banyak standar
zameb

1
@zameb: Saya akan mengatakan, aturan StyleCop adalah salah satu pedoman pengkodean paling umum untuk C #. Saat mengkode dalam bahasa apa pun, saya selalu berusaha menemukan kumpulan pedoman pengkodean yang paling umum, dan mengikuti mereka.
Gerwald

5

Dari StyleCop

bidang pribadi, bidang publik, konstruktor, properti, metode publik, metode pribadi

Karena StyleCop adalah bagian dari proses pembuatan MS, Anda dapat melihatnya sebagai standar de facto


Menarik. Apakah Anda menggunakan StyleCop secara teratur?
mmcdole

Untuk satu proyek ya, karena memang digunakan untuk beberapa pekerjaan kontrak MS sekarang dan lagi. Seringai
blowdart

1
Menggunakan StyleCop untuk waktu yang lama dan jika menggunakan rekomendasi itu membuat kode benar-benar lebih mudah dibaca: Jika membuka file .cs kelas saya segera melihat metode publik yang "lebih penting" daripada yang pribadi. Publik adalah "antarmuka" kelas yang ditawarkannya dan apa yang dapat diuji (lebih disukai TDD, dan Test-First)
hfrmobile

1
Menurut StyleCop, bidang publik harus didahului
Michael Freidgeim

1
Apa yang Anda maksud dengan "StyleCop adalah bagian dari proses pembuatan MS"? Apakah microsoft menggunakan StyleCop untuk semua kodenya?
Rico Suter

5

Biasanya saya mencoba mengikuti pola berikut:

  • anggota statis (biasanya memiliki konteks lain, harus aman thread, dll.)
  • anggota contoh

Setiap bagian (statis dan instance) terdiri dari jenis anggota berikut:

  • operator (selalu statis)
  • bidang (diinisialisasi sebelum konstruktor)
  • konstruktor
  • destructor ( adalah tradisi untuk mengikuti konstruktor )
  • properti
  • metode
  • acara

Kemudian anggota diurutkan berdasarkan visibilitas (dari kurang ke lebih terlihat):

  • pribadi
  • intern
  • dilindungi internal
  • terlindung
  • publik

Urutannya bukan dogma: kelas sederhana lebih mudah dibaca, namun, kelas yang lebih kompleks membutuhkan pengelompokan khusus konteks.


5

Preferensi saya adalah memesan berdasarkan jenis dan kemudian mengurangi visibilitas sebagai berikut

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

Saya tahu ini melanggar Style Cop dan jika seseorang dapat memberi saya alasan yang bagus mengapa saya harus menempatkan detail implementasi jenis sebelum antarmuka, saya bersedia mengubah. Saat ini, saya memiliki preferensi yang kuat untuk menempatkan anggota pribadi yang terakhir.

Catatan: Saya tidak menggunakan bidang publik atau yang dilindungi.


3
Sepakat. Saya benar-benar bertanya-tanya apakah gagasan untuk menempatkan anggota pribadi lebih dulu bukanlah peninggalan dari hari C di mana variabel harus dideklarasikan terlebih dahulu. Saya hampir selalu ingin melihat antarmuka publik terlebih dahulu, bukan internal kelas.
Matt Davis

1
Itu benar-benar masuk akal. Saya yakin itu adalah peninggalan dari C.
Aluan Haddad

Beberapa gotcha terbesar adalah properti IMO. Ketika ada logika pada pengambil / penyetel yang tidak Anda sadari, itu akan jauh lebih mungkin menggigit daripada efek samping dalam metode (yang Anda perkirakan akan terjadi) Oleh karena itu, saya lebih suka properti di samping bidangnya di atas , jadi ketika saya melihat kelas untuk pertama kalinya, saya melihat gotcha di bagian atas. Sedangkan ketika saya membaca sebuah metode, saya biasanya menavigasi / segera melompat ke metode pula
Ryan The Leach


3

satu-satunya pedoman pengkodean yang saya lihat disarankan untuk ini adalah meletakkan bidang di bagian atas definisi kelas.

saya cenderung menempatkan konstruktor berikutnya.

komentar umum saya adalah bahwa Anda harus tetap berpegang pada satu kelas per file dan jika kelasnya cukup besar sehingga organisasi properti versus metode menjadi perhatian besar, seberapa besar kelasnya dan haruskah Anda refactoring? apakah itu mewakili beberapa masalah?


3
dan begitu Anda membutuhkan daerah ... Anda telah kehilangan.
Hamish Smith

3

Saya lebih suka menempatkan bidang pribadi di bagian atas bersama dengan konstruktor, kemudian menempatkan bit antarmuka publik setelah itu, kemudian bit antarmuka pribadi.

Juga, jika definisi kelas Anda cukup lama untuk memesan barang menjadi penting, itu mungkin bau kode yang menunjukkan kelas Anda terlalu besar dan kompleks dan Anda harus refactor.


3

Saya menyimpannya sesederhana mungkin (setidaknya untuk saya)

Enumerasi
Deklarasi
Konstruktor
Mengesampingkan
Metode
Properties
Event Handler


2

Tentu saja tidak ada dalam bahasa yang memberlakukannya dengan cara apa pun. Saya cenderung mengelompokkan berbagai hal berdasarkan visibilitas (publik, kemudian dilindungi, kemudian pribadi) dan menggunakan #region untuk mengelompokkan hal-hal terkait secara fungsional, terlepas dari apakah itu properti, metode, atau apa pun. Metode konstruksi (apakah fungsi sebenarnya atau fungsi pabrik statis) biasanya tepat di atas karena mereka adalah hal pertama yang perlu diketahui klien.


Saya menggunakan daerah untuk memisahkan dengan visibilitas juga, dan memiliki tata letak kode Regionerate membuat saya jujur. rauchy.net/regionerate
Forgotten Semicolon

Saya tidak melihat masalah dengan menggunakan #regions, namun saya sering menemukan bahwa begitu saya tergoda untuk menempatkan di suatu wilayah, itu mendorong saya untuk mempertimbangkan memecah kelas saya.
mikecamimo

2

Saya tahu ini sudah lama tetapi pesanan saya adalah sebagai berikut:

dalam urutan publik, dilindungi, pribadi, internal, abstrak

  • Konstanta
  • Variabel statis
  • Bidang
  • Acara
  • Konstruktor
  • Metode
  • Properti
  • Delegasi

Saya juga suka menulis properti seperti ini (bukan pendekatan steno)

// 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; }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.