Apa konvensi penamaan yang baik untuk tipe generik dalam C #? [Tutup]


16

Saya memutuskan untuk mengajukan pertanyaan ini di sini alih-alih di stack overflow karena agak subyektif.

Dalam C #, biasanya saya melihat tipe generik dengan nama yang sangat buruk. Secara khusus, "T" umumnya digunakan tetapi bukan nama yang bermakna dengan sendirinya. Sebagai contoh:

class Fruit<T>
{
    T fruit;
}

Meskipun ini adalah pendekatan yang umum, adakah yang akan merekomendasikan hal ini? Dan jika demikian, apa konvensi penamaan yang masuk akal untuk tipe generik dalam konteks C # untuk fungsi dan kelas generik?

Dalam contoh saya sebelumnya, mari kita asumsikan bahwa jenis generik Tharus selalu menjadi jenis buah, seperti Appleatau Orange. Jenisnya Tperlu memperjelas bahwa itu adalah jenis buah, jadi mungkin nama yang lebih baik FruitType, jadi kita berakhir dengan:

class Fruit<FruitType>
{
    FruitType fruit;
}

Ini hanya untuk memberi kalian ide tentang apa yang saya cari. Apa "aturan praktis" yang dapat diterima untuk masalah ini?


3
Ini bukan pertanyaan yang konstruktif. Itu hanya akan mendapatkan jawaban dengan gaya favorit poster.
Michael K

1
Lihatlah kendala, dengan mempertimbangkan contoh Anda: msdn.microsoft.com/en-us/library/d5x73970.aspx#Y426
Matthieu

2
@Michael akan ada sejumlah jawaban, dan jawaban yang diterima akan menjadi favorit Robert, tetapi berbagai jawaban lainnya akan dipilih.
StuperUser

5
@Michael Pertanyaan subyektif mendapat jawaban subyektif. Pertanyaannya masih konstruktif karena berfungsi sebagai titik referensi bagi siapa pun yang menginginkan berbagai ide / solusi untuk masalah khusus ini. Yang saya tandai sebagai jawabannya tidak mewakili satu-satunya informasi yang berguna.
void.pointer

Mungkin mengubahnya menjadi wiki komunitas, sebagai sumber daya yang bagus, meskipun subjektif,?
tylermac

Jawaban:


22

Sungguh subyektif ... ish .
Karena beberapa orang menemukan iitu benar-benar valid untuk variabel loop, beberapa orang berpikir Tsangat valid untuk tipe place-holder di kelas generik.

Saya pribadi mendukung pendekatan ini, itu adalah konvensi umum dan orang-orang umumnya tahu apa yang Anda maksud.

Di mana jenisnya bermakna saya akan menggunakan nama yang bermakna, tetapi umumnya memulainya dengan T. Saya baru-baru ini mengembangkan kelas kamus umum (jangan tanya) dan deklarasi itu

public class Dictionary<TKey, TValue>

Namun, untuk sesuatu seperti Tuple, di mana jenis-jenisnya pada dasarnya tidak berarti, saya menganggap yang berikut ini benar-benar dapat diterima.

public class Tuple<T1, T2, T3>

2
Saya tidak menemukan ini subjektif sama sekali. idan Tbekerja, dan ini pada prinsipnya dapat diukur (yaitu dapat diukur apakah pemahaman kode sumber meningkat jika, katakanlah, indeks loop mendapatkan pengidentifikasi yang berbeda). Hanya karena sulit untuk mengukur bukan berarti kita harus memberi label "subyektif" pada semuanya. Mengingat penggunaannya yang luas tanpa masalah yang jelas, cukup masuk akal untuk mengatakan bahkan tanpa mengukur bahwa ini memang bekerja.
Konrad Rudolph

2
@ Konrad: Anda benar. . . Namun pertanyaannya tidak ditandai sebagai subyektif, penanya mengakui itu adalah topik subjektif seandainya orang cenderung memiliki preferensi mereka sendiri pada konvensi penamaan. Jadi sementara pertanyaannya mungkin tidak subyektif (dan pada kenyataannya itu bukan karena ada jawaban yang benar yaitu jawaban yang terhubung ke pedoman resmi Microsoft) topiknya subyektif, karena saya yakin seseorang akan memposting " idan Titu jahat . Orang tidak boleh menggunakan nama huruf tunggal" ketik jawaban. Telah menambahkan ish untuk membantu memuaskan semua orang :)
Binary Worrier

1
Saya pikir komentar saja ditambahkan ke posting ini membuatnya menjadi respon yang sangat berharga, walaupun jawabannya sendiri sangat membantu. Tmasuk akal ketika kita berbicara tentang jenis tanpa kendala, TFruitmasuk akal karena ia berkata kepada saya "Setiap jenis dengan kendala bahwa itu adalah buah". Ini sepertinya "aturan praktis" yang bagus untuk penamaan parameter tipe generik. Terima kasih!!
void.pointer

1
Sebagai catatan, ini selaras dengan .NET Framework Design Guidelines untuk pengembang Library dari MSDN. Lihat: Nama Parameter Tipe Umum .
Berikan Thomas

7

Saya pikir Anda benar, meskipun T telah menjadi standar. Mungkin berasal dari waktu C ++ lama dan kata-kata "dari tipe T". Saya menganggap itu praktik yang baik untuk menjadi deskriptif mungkin, tapi itu subjektif.

Anda dapat memilih T sebagai awalan, seperti halnya banyak orang memilih I untuk antarmuka. Jadi

class Juice<TFruit> where TFruit...

akan menjadi nama baik menurut pendapat saya. Saya lebih suka awalan daripada sufiks dalam banyak kasus, karena dengan segera jelas apa yang Anda lihat ketika Anda menemukannya dan lebih mudah untuk mencari hal-hal seperti Intellisense. Ini adalah praktik yang baik untuk Kontrol-UI, juga, ketika Anda kemungkinan besar selalu tahu jenisnya (mis. TextBox) tetapi tidak 100% yakin tentang nama deskriptif yang Anda berikan.

Sisi negatifnya adalah, terlihat buruk ketika tipe itu sendiri dimulai dengan T. Jadi saya pikir akan lebih baik jika suffix tipe generik dalam kasus khusus, seperti yang di bawah ini.

class SomeAlgorithm<TypeT> where TypeT : Type

Harap dicatat bahwa ini hanya pendapat saya dan sangat subjektif. Tapi saya pikir saya punya poin kecil dengan lebih memilih awalan daripada suffixing.


Penggunaan Tawalan untuk parameter tipe dan Iuntuk nama antarmuka diwajibkan secara eksplisit ( aturan " DO ...") dalam Pedoman Desain Kerangka.
Richard

1
Itu dipertanyakan apa yang digunakan di TFruitsini membawa ke atas meja T. Menggunakan nama seperti TTypeatau TypeTtentu saja tidak masuk akal. Itu tidak menambahkan informasi apa pun selain hanya T. Informasi yang sama persis disampaikan.
Konrad Rudolph

@Konrad Rudolph: Perhatikan contoh TypeT saya, ini mencakup kasus khusus ketika berhadapan dengan System.Type. Saya pikir nama saya memiliki entropi yang lebih tinggi daripada hanya menggunakan T untuk tipe, terutama jika generik juga dibatasi.
Falcon

7

Microsoft memiliki pedoman resmi tentang obat generik: Nama Kelas, Struktur, dan Antarmuka (dikutip di sini , dan dalam bentuk buku: Kerangka Desain Pedoman ).

Mengenai pertanyaan spesifik Anda dikatakan:

Beri nama parameter tipe generik dengan nama deskriptif, kecuali nama huruf tunggal sepenuhnya jelas dan nama deskriptif tidak akan menambah nilai.

IDictionary<TKey, TValue> 

adalah contoh antarmuka yang mengikuti panduan ini.

Pertimbangkan untuk menggunakan huruf T sebagai nama parameter tipe untuk tipe dengan satu parameter tipe huruf tunggal.

Lakukan awalan nama parameter tipe deskriptif dengan huruf T.

Pertimbangkan untuk menunjukkan batasan yang ditempatkan pada parameter tipe atas nama parameter. Misalnya, parameter yang dibatasi untuk ISession dapat disebut TSession.


Referensi yang lebih baik adalah buku Kerangka Desain Pedoman atau (ringkasan) pada MSDN, terutama Nama Kelas, Struktur, dan Antarmuka .
Richard

@ Richard: menyesuaikan jawaban saya dengan mempertimbangkan komentar Anda, Terima kasih!
Matthieu

2

Inti dari generik adalah mendelegasikan fungsionalitas - kelas generik melakukan satu hal, argumennya melakukan hal lain. Contoh buku teks adalah koleksi generik: koleksi menyimpan 'barang', tetapi tidak peduli benda apa itu. Nama generik (sic!), Dengan demikian, memiliki logika tertentu untuk itu - kami tidak ingin itu menjadi deskriptif, karena tidak ada yang bisa dijelaskan selain "itu argumen tipe generik", yang Tmencakup namanya secara mendalam (mempertimbangkan konvensi). Menjadi deskriptif itu baik, tetapi terlalu deskriptif menunjukkan batasan yang tidak ada.

Namun, kadang-kadang, kelas atau metode generik memiliki lebih dari satu jenis parameter, dan pada titik ini, masuk akal untuk memberi mereka lebih banyak nama deskriptif, sehingga peran mereka menjadi jelas. Contoh yang baik adalah untuk jenis pengumpulan nilai-kunci, di mana kunci dan nilai bersifat generik; memanggil mereka Tdan S(atau Qapa pun) akan kurang berguna daripada memanggil mereka, katakan, KeyTypedan ValueType, atau TKeydan TVal.


1

Jawabannya memang subyektif. Namun, itu memang pantas sebagai pertanyaan, karena kode harus mendokumentasikan sendiri, dan kita semua bisa belajar beberapa cara yang lebih baik untuk melakukannya.

Berikut ini adalah konvensi yang saya pelajari dan ikuti:

  • Parameter tipe generik tidak boleh keliru untuk kelas beton. Ini umumnya mendorong pengantar Tterlepas dari apa pun yang mengikuti, seperti antarmuka umumnya diawali dengan I.

  • Parameter tipe generik tunggal pada kelas atau metode biasanya harus diberi label T. Ini adalah konvensi yang hampir dipahami secara universal sejak Templat C ++.

  • Beberapa parameter tipe generik pada deklarasi metode atau kelas yang sama semuanya harus dimulai dengan T, tetapi dibedakan dengan beberapa cara yang ringkas namun dapat dimengerti. TIndan TOut, misalnya, adalah GTP yang umum dan dipahami dengan baik untuk metode yang menerima input generik yang sangat diketik dan menghasilkan output generik yang sangat diketik.

  • Beberapa tipe yang berbeda tetapi tidak biasa, seperti untuk kelas yang berisi seperti Tuple .Net atau tipe delegasi seperti Func, Predicate, dan Action, dapat diberi label T1, T2, T3, dll. Namun, deklarasi GTP "luar biasa" (memiliki tujuan dan tujuan yang pasti / atau batasan jenis yang sangat spesifik) harus memiliki sesuatu yang lebih deskriptif.

  • Tipe generik tunggal pada suatu metode, yang berbeda dari tipe generik dari kelas yang berisi, dapat mengikuti aturan sebelumnya mengenai beberapa tipe dalam kelas atau metode, ATAU jika tipe tidak biasa selain berbeda maka dapat diberikan perbedaan satu huruf, sering Uatau V. Sekali lagi ini adalah konvensi yang berasal dari templat C ++.

  • Apa pun yang Anda pilih untuk dilakukan, tetap konsisten; jangan memberi label GTP untuk satu kelas T, dan yang berikutnya TParam, kecuali kelas kedua bersarang di kelas pertama sehingga Ttidak tersedia untuk digunakan di kelas kedua.

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.