Apakah ada setara typedef dalam C #, atau cara lain untuk mendapatkan semacam perilaku yang serupa? Saya telah melakukan beberapa googling, tetapi di mana-mana saya kelihatannya negatif. Saat ini saya memiliki situasi yang mirip dengan yang berikut:
class GenericClass<T>
{
public event EventHandler<EventData> MyEvent;
public class EventData : EventArgs { /* snip */ }
// ... snip
}
Sekarang, tidak perlu ilmuwan roket untuk mengetahui bahwa ini dapat dengan cepat menyebabkan banyak pengetikan (permintaan maaf untuk permainan kata-kata yang mengerikan) ketika mencoba menerapkan penangan untuk acara itu. Itu akan berakhir seperti ini:
GenericClass<int> gcInt = new GenericClass<int>;
gcInt.MyEvent += new EventHandler<GenericClass<int>.EventData>(gcInt_MyEvent);
// ...
private void gcInt_MyEvent(object sender, GenericClass<int>.EventData e)
{
throw new NotImplementedException();
}
Kecuali, dalam kasus saya, saya sudah menggunakan tipe yang kompleks, bukan hanya int. Akan lebih baik jika memungkinkan untuk menyederhanakan ini sedikit ...
Edit: mis. mungkin mengetikkan EventHandler daripada perlu mendefinisikannya kembali untuk mendapatkan perilaku yang sama.
using MyClassDictionary = System.Collections.Generic.Dictionary<System.String, MyNamespace.MyClass>;
Apakah itu benar? Kalau tidak, tampaknya tidak mempertimbangkanusing
definisi di atasnya.typedef uint8 myuuid[16];
melalui "menggunakan" arahan.using myuuid = Byte[16];
tidak dikompilasi.using
dapat digunakan hanya untuk membuat alias tipe .typedef
tampaknya jauh lebih fleksibel, karena dapat membuat alias untuk seluruh deklarasi (termasuk ukuran array). Apakah ada alternatif dalam hal ini?Jon benar-benar memberikan solusi yang bagus, saya tidak tahu Anda bisa melakukannya!
Kadang saya terpaksa mewarisi dari kelas dan menciptakan konstruktornya. Misalnya
Bukan solusi terbaik (kecuali majelis Anda digunakan oleh orang lain), tetapi berhasil.
sumber
public class FooList : LikeType<IReadOnlyList<Foo>> { ... }
dan kemudian menggunakannya di mana saja Anda akan mengharapkanIReadOnlyList<Foo>
. Jawaban saya di bawah ini menunjukkan lebih detail.Foo
jika diteruskan ke mis. Metode templat yang menerimaList<T>
. Dengan mengetikkan yang tepat itu akan mungkin.Jika Anda tahu apa yang Anda lakukan, Anda dapat mendefinisikan kelas dengan operator implisit untuk mengkonversi antara kelas alias dan kelas aktual.
Saya sebenarnya tidak mendukung ini dan belum pernah menggunakan sesuatu seperti ini, tetapi ini mungkin bisa bekerja untuk beberapa keadaan tertentu.
sumber
C # mendukung beberapa kovarian bawaan untuk delegasi acara, jadi metode ini seperti ini:
Dapat digunakan untuk berlangganan acara Anda, tidak ada pemeran eksplisit yang diperlukan
Anda bahkan dapat menggunakan sintaks lambda dan intellisense akan dilakukan untuk Anda:
sumber
Saya pikir tidak ada typedef. Anda hanya bisa mendefinisikan tipe delegasi tertentu daripada yang umum di GenericClass, yaitu
Ini akan membuatnya lebih pendek. Tetapi bagaimana dengan saran berikut:
Gunakan Visual Studio. Dengan cara ini, saat Anda mengetik
itu sudah menyediakan tanda tangan event handler yang lengkap dari Intellisense. Tekan TAB dan itu ada di sana. Terima nama pawang yang dihasilkan atau ubah, lalu tekan TAB lagi untuk menghasilkan puntung rintisan secara otomatis.
sumber
Baik C ++ dan C # tidak ada cara mudah untuk membuat tipe baru yang secara semantik identik dengan tipe yang ada. Saya menemukan 'typedef' seperti itu benar-benar penting untuk pemrograman tipe-aman dan itu memalukan c # tidak memilikinya Perbedaan antara
void f(string connectionID, string username)
kevoid f(ConID connectionID, UserName username)
jelas ...(Anda dapat mencapai hal serupa di C ++ dengan meningkatkan di BOOST_STRONG_TYPEDEF)
Mungkin tergoda untuk menggunakan warisan tetapi itu memiliki beberapa batasan utama:
Satu-satunya cara untuk mencapai hal serupa di C # adalah dengan menyusun tipe kami di kelas baru:
Meskipun ini akan berhasil, sangat verbose hanya untuk typedef. Selain itu kami memiliki masalah dengan serialisasi (yaitu untuk Json) karena kami ingin membuat cerita bersambung kelas melalui properti Composed-nya.
Di bawah ini adalah kelas pembantu yang menggunakan "Curiously Recurring Pattern Pattern" untuk membuatnya lebih sederhana:
Dengan Composer, kelas di atas menjadi sederhana:
Dan selain itu
SomeTypeTypeDef
akan bersambung ke Json dengan cara yangSomeType
sama.Semoga ini membantu !
sumber
Anda dapat menggunakan pustaka sumber terbuka dan paket NuGet bernama LikeType yang saya buat yang akan memberi Anda
GenericClass<int>
perilaku yang Anda cari.Kode akan terlihat seperti:
sumber
LikeType
perpustakaan.LikeType
Tujuan utama adalah untuk membantu dengan Obsesi Primitif , dan karena itu, tidak ingin Anda dapat membagikan jenis yang dibungkus seperti itu adalah jenis pembungkus. Seperti pada, jika saya membuatAge : LikeType<int>
maka jika fungsi saya membutuhkanAge
, saya ingin memastikan penelepon saya melewatiAge
, bukanint
.Ini kode untuk itu, selamat menikmati !, saya mengambilnya dari dotNetReference, ketik pernyataan "using" di dalam namespace line 106 http://referencesource.microsoft.com/#mscorlib/microsoft/win32/win32native.cs
sumber
Untuk kelas yang tidak disegel cukup mewarisi dari mereka:
Tetapi untuk kelas tertutup, dimungkinkan untuk mensimulasikan perilaku typedef dengan kelas dasar seperti itu:
sumber
Alternatif terbaik
typedef
yang saya temukan di C # adalahusing
. Sebagai contoh, saya dapat mengontrol presisi float melalui flag compiler dengan kode ini:Sayangnya, Anda harus menempatkan ini di bagian atas setiap file tempat Anda menggunakan
real_t
. Saat ini tidak ada cara untuk mendeklarasikan tipe namespace global dalam C #.sumber