Membaca ini , saya belajar bahwa memungkinkan metode untuk menerima parameter dari berbagai jenis dengan menjadikannya metode generik. Dalam contoh, kode berikut digunakan dengan batasan tipe untuk memastikan "U" adalah IEnumerable<T>
.
public T DoSomething<U, T>(U arg) where U : IEnumerable<T>
{
return arg.First();
}
Saya menemukan beberapa kode lagi yang memungkinkan menambahkan beberapa batasan tipe, seperti:
public void test<T>(string a, T arg) where T: ParentClass, ChildClass
{
//do something
}
Namun, kode ini muncul untuk menegakkan yang arg
harus berupa tipe ParentClass
dan ChildClass
. Yang ingin saya lakukan adalah mengatakan bahwa arg bisa berupa ParentClass
atau ChildClass
dengan cara berikut:
public void test<T>(string a, T arg) where T: string OR Exception
{
//do something
}
Bantuan Anda dihargai seperti biasa!
c#
asp.net-mvc-3
types
Mansfield
sumber
sumber
where T : string
, sebagaistring
adalah disegel kelas. Satu-satunya hal berguna yang dapat Anda lakukan adalah mendefinisikan kelebihanstring
danT : Exception
, seperti yang dijelaskan oleh @ Botz3000 dalam jawabannya di bawah ini.arg
adalah yang ditentukan olehobject
- jadi mengapa tidak hanya menghapus obat generik dari gambar dan membuat jenisnyaarg
object
? Apa yang kamu dapat?Jawaban:
Itu tidak mungkin. Namun, Anda dapat menentukan kelebihan beban untuk jenis tertentu:
Jika itu adalah bagian dari kelas generik, mereka akan lebih disukai daripada versi generik dari metode ini.
sumber
or
hubungan membuat hal-hal yang jauh dari umum menjadi berguna. Anda harus melakukan refleksi untuk mencari tahu apa yang harus dilakukan dan semua itu. (YUCK!).Jawaban botz 100% benar, berikut penjelasan singkatnya:
Saat Anda menulis sebuah metode (generik atau tidak) dan mendeklarasikan tipe-tipe parameter yang digunakan metode tersebut, Anda mendefinisikan sebuah kontrak:
Jika Anda mencoba dan memberikannya lebih dari satu jenis pada satu waktu (dengan memiliki atau) atau mencoba membuatnya mengembalikan nilai yang mungkin lebih dari satu jenis yang membuat kontrak menjadi kabur:
Masalahnya adalah bahwa ketika Anda masuk ke metode Anda tidak tahu apakah mereka telah memberi Anda
IJumpRope
atauPiFactory
. Selain itu, ketika Anda melanjutkan dan menggunakan metode ini (dengan asumsi bahwa Anda telah mengkompilasi secara ajaib), Anda tidak benar-benar yakin jika Anda memilikiFisher
atauAbstractConcreteMixer
. Pada dasarnya itu membuat semuanya jauh lebih membingungkan.Solusi untuk masalah Anda adalah salah satu dari dua kemungkinan:
Tetapkan lebih dari satu metode yang menentukan setiap kemungkinan transformasi, perilaku, atau apa pun. Itu jawaban Botz. Dalam dunia pemrograman ini disebut sebagai Overloading the method.
Tentukan kelas dasar atau antarmuka yang tahu bagaimana melakukan semua hal yang Anda butuhkan untuk metode ini dan minta satu metode mengambil tipe itu saja . Ini mungkin melibatkan membungkus a
string
danException
di kelas kecil untuk menentukan bagaimana Anda merencanakan pemetaan mereka untuk implementasi, tetapi kemudian semuanya sangat jelas dan mudah dibaca. Saya bisa datang, empat tahun dari sekarang dan membaca kode Anda dan dengan mudah memahami apa yang terjadi.Yang Anda pilih tergantung pada seberapa rumit pilihan 1 dan 2 akan menjadi dan seberapa luas itu perlu.
Jadi untuk situasi spesifik Anda, saya akan membayangkan Anda hanya mengeluarkan pesan atau sesuatu dari pengecualian:
Sekarang yang Anda butuhkan adalah metode yang mengubah
string
danException
menjadi IHasMessage. Sangat mudah.sumber
Jika ChildClass berarti berasal dari ParentClass, Anda dapat menulis yang berikut ini untuk menerima ParentClass dan ChildClass;
Di sisi lain, jika Anda ingin menggunakan dua jenis yang berbeda tanpa hubungan pewarisan di antara mereka, Anda harus mempertimbangkan jenis yang mengimplementasikan antarmuka yang sama;
maka Anda dapat menulis fungsi generik Anda sebagai;
sumber
Setua pertanyaan ini saya masih mendapatkan upvotes acak pada penjelasan saya di atas. Penjelasannya masih sangat bagus, tetapi saya akan menjawab untuk yang kedua kalinya dengan tipe yang sangat membantu saya sebagai pengganti untuk tipe-tipe serikat (jawaban yang sangat diketik untuk pertanyaan yang tidak secara langsung didukung oleh C # sebagaimana adanya ).
Kelas di atas mewakili tipe yang bisa berupa TP atau TA. Anda dapat menggunakannya seperti itu (tipe merujuk kembali ke jawaban asli saya):
Catatan penting:
IsPrimary
terlebih dahulu.IsNeither
IsPrimary
atauIsAlternate
.Primary
danAlternate
Either
di mana saja di mana orang diharapkan. Jika Anda melakukan lulusEither
di manaTA
atauTP
diharapkan, tetapiEither
mengandung salah jenis nilai Anda akan mendapatkan error runtime.Saya biasanya menggunakan ini di mana saya ingin metode mengembalikan hasil atau kesalahan. Itu benar-benar membersihkan kode gaya itu. Saya juga sangat jarang ( jarang ) menggunakan ini sebagai pengganti metode kelebihan beban. Secara realistis ini adalah pengganti yang sangat buruk untuk kelebihan seperti itu.
sumber