Apa cara terbaik untuk menyusun dan memberi nama file yang berisi kelas generik dengan nama yang sama?


14

Dalam proyek saya saat ini, saya menemukan persyaratan untuk membuat kelas generik dengan nama yang sama, tetapi jumlah parameter generik yang berbeda. Sebagai contoh:

MyClass<T1>
MyClass<T1, T2>
MyClass<T1, T2, T3>

Mengingat bahwa saya ingin semua ini di namespace yang sama, saya bingung bagaimana cara menyusun dan memberi nama kelas dan file saya?

Jika kita mengikuti gagasan bahwa kita harus memiliki kelas terbatas pada satu per file dan bahwa file harus dalam struktur folder yang mewakili hirarki namespace dan bahwa nama file harus sesuai dengan nama kelas, bagaimana cara menangani situasi ini ?

Apa yang sebenarnya saya tanyakan di sini adalah apa yang harus saya beri nama file yang berisi MyClass<T1>, dan apa yang harus saya beri nama file yang berisi MyClass<T1, T2>? Saya tidak bertanya apa nama parameter tipe seharusnya.


Beri kami beberapa contoh spesifik yang menggambarkan masalah dengan lebih baik. Contoh yang Anda berikan terlalu ... erm, generik. Apa yang Anda maksud dengan "bagaimana menyusun dan memberi nama kelas dan file saya?"
Robert Harvey

Microsoft melakukan ini sendiri dengan hanya menambahkan nomor ke parameter tipe. Lihat dokumen Tuple: msdn.microsoft.com/en-us/library/…
Pete

@Pete: Itu benar-benar hanya berlaku untuk Tuple. Microsoft juga menggunakan TKey, TValuekonvensi. Fungsi memiliki TResultparameter tipe. Meskipun saya setuju bahwa Anda dapat menggunakan T1,, T2dll. Untuk sejumlah variabel parameter input yang tidak memiliki penggunaan spesifik seperti TKeydan TValue.
Robert Harvey

@RobertHarvey Ya, ya, tetapi hanya dalam konteks koleksi kunci / nilai aktual seperti kamus. Untuk apa pun yang terdiri dari sejumlah variabel jenis mereka menambahkan nomor. Berikut contoh lain: msdn.microsoft.com/en-us/library/dd402872(v=vs.110).aspx
Pete

1
Ya, suntingan Anda usang beberapa komentar. :) Kenapa kamu tidak bisa menyimpan kelas-kelas itu di file fisik yang sama? Jika mereka sangat berbeda sehingga Anda perlu menyimpannya dalam file yang terpisah, dapatkah Anda memberi tahu kami apa yang membuatnya berbeda?
Pete

Jawaban:


14
MyGenericClass`1.cs
MyGenericClass`2.cs
MyGenericClass`3.cs

Dan seterusnya, di mana angka setelah backtick adalah jumlah parameter tipe generik. Konvensi ini digunakan oleh Microsoft.

Atau, Anda dapat menggunakan sesuatu seperti

MyGenericCollectionClass[TKey, TValue].cs

yang mempertahankan tidak hanya jumlah parameter tipe generik, tetapi juga nama spesifiknya. Memang, itu tidak mempertahankan kurung sudut, tetapi kita tidak dapat memiliki semua yang kita inginkan dalam hidup ini, bukan?


1
Compiler secara internal menguraikan nama tipe generik, menambahkan backtick dan jumlah parameter generik sejak. NET tidak mengizinkan beberapa tipe dengan nama yang sama dengan jumlah parameter generik yang berbeda tetapi C # tidak. Jadi konvensi penamaan file cocok dengan apa yang dilakukan kompiler.
CodesInChaos

1
Saya ingin membuktikan Anda salah, tetapi sebenarnya Anda benar: github.com/dotnet/corefx/tree/master/src/… Saya tidak suka konvensi ini.
Den

1
@Den, tampaknya sekarang mereka menyesal dari kebaktian itu. Mungkin itu menyiratkan beberapa masalah? github.com/dotnet/corefx/commit/…
Sam

@ Sam Semoga, bukan masalah komunikasi antara tim Microsoft. Karena tidak ada orang lain yang melakukannya. Juga terserah tim penyusun, bukan tim perpustakaan untuk memutuskan menurut pendapat saya.
Den

Saya tidak punya nyali untuk menggunakan "` "dalam nama file.
Cristian E.

4

Dalam kasus Tupledan Actionyang disebutkan Pete, Microsoft sendiri menggunakan satu file - lihat Tuple.cs dan Action.cs .

Saya pikir itu sebagian tergantung pada apakah atau tidak fungsi untuk semua kelas pada dasarnya sama. Secara pribadi saya tidak suka kelas lumping ke dalam satu file, tetapi ini mungkin pengecualian. Dalam kode sumber tempat saya bekerja saya menambahkan kelas autogenerated (menggunakan T4) NamedTupleyang bertindak dengan cara yang sama Tuple, tetapi dengan nama string sebagai argumen pertama ke konstruktor.

Untuk menjawab pertanyaan Anda, jika Anda tidak ingin menggunakan satu file, mungkin gunakan MyClass_1.cs untuk MyClass<T1>, MyClass_2.cs untuk MyClass<T1, T2>, dll.

Namun, tidak ada opsi yang ideal, jadi saya cenderung menyarankan argumen "Microsoft melakukannya dengan cara ini, jadi ...".


2
Tupledan Actionsemuanya adalah delegasi; mereka tidak memiliki kode implementasi, jadi menempatkan semua variasi dalam file yang terpisah akan menjadi sia-sia. Buktikan saja bahwa setiap aturan memiliki pengecualian.
Robert Harvey

Ya secara umum menempatkan beberapa delegasi publik ke dalam file yang sama dianggap ok (asalkan mereka terkait).
Stephen

1
@RobertHarvey, Tuplebukan merupakan delegasi, tetapi setiap implementasi tetap singkat.
Arturo Torres Sánchez

@ ArturoTorresSánchez: Benar, saya sedang memikirkan Func.
Robert Harvey

0

Pernahkah Anda bertanya pada diri sendiri, apakah kelas benar-benar memiliki maksud yang sama? Jika satu kelas lebih umum daripada yang lain, maka itu akan menjadi GenericClass , MoreGenericClass dan MostGenericClass . Bayangkan bahwa setiap parameter tipe kelas menambahkan dimensi baru ke kelas, sehingga mungkin membantu untuk bertanya dimensi apa itu.

Mari kita ambil contoh ini:

  • Container<Thing>
  • MetricContainer<Thing, Metric>
  • MetricTransportableContainer<Thing, Metric, Transport>

Saya sadar, ini bukan contoh terbaik, tetapi sangat ekspresif untuk menunjukkan tiga dimensi:

  • Dimensi batin, apa yang bisa dimuat
  • Dimensi metrik, yang dengannya metrik dapat dimuat, hanya berdasarkan jumlah benda atau ukuran persegi atau dengan kapasitas kubik atau berat
  • Dimensi luar, tempat dapat dimuat.

Jadi Anda dapat memodelkan transportasi mobil:

Container<Cars>
MetricContainer<Cars, CountMetric>
MetricTransportableContainer<Cars, CountMetric, Ship>

Transportasi cairan:

Container<Fluid>
MetricContainer<Fluid, Volume>
MetricTransportableContainer<Fluid, Volume, Shelf>

Transportasi energi:

Container<Energy>
MetricContainer<Energy, ElectricPower>
MetricTransportableContainer<Energy, ElectricPower, Box>

Pengangkutan gula, sereal:

Container<CrumblyMaterial>
MetricContainer<CrumblyMaterial, Weight>
MetricTransportableContainer<CrumblyMaterial, Weight, Silo>

Oh, sungguh mengejutkan: a List<T>memiliki satu dimensi yang mewakili hal-hal yang dapat dipegang oleh daftar; dan ini adalah Map<T, S>dengan dua dimensi yang mewakili hal-hal yang dapat dipegang oleh peta dan tombol akses.


1
Saya pikir Anda tidak mengerti pertanyaan itu. Lihatlah paragraf terakhir dari pertanyaan.
Robert Harvey

1
@RobertHarvey Harap baca pertanyaan dengan seksama: classname harus sesuai dengan nama file. Itu dipertukarkan. Masalahnya terletak pada analisis yang salah dari kelas dan penamaan yang salah dari kelas generik secara umum. Singkatnya jawaban saya: "Sebutkan apa itu dan bukan apa yang kelihatannya."
shylynx


1
@RobertHarvey Baca jawaban saya: Masukkan satu kelas ke dalam satu file!
shylynx

1
Saya pikir Anda tidak mengerti intinya. Pertanyaannya bertanya: Bagaimana cara saya menempatkan Tuple<T1>, Tuple<T1, T2>dan Tuple<T1, T2, T3>ke dalam file CS terpisah dengan cara standar, tanpa bentrok nama?
Robert Harvey
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.