Saya mencoba membuat ekstensi umum yang menggunakan 'TryParse' untuk memeriksa apakah string adalah tipe yang diberikan:
public static bool Is<T>(this string input)
{
T notUsed;
return T.TryParse(input, out notUsed);
}
ini tidak dapat dikompilasi karena tidak dapat menyelesaikan simbol 'TryParse'
Seperti yang saya mengerti, 'TryParse' bukan bagian dari antarmuka apa pun.
Apakah ini bisa dilakukan?
Memperbarui:
Menggunakan jawaban di bawah ini saya telah menemukan:
public static bool Is<T>(this string input)
{
try
{
TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(input);
}
catch
{
return false;
}
return true;
}
Ini berfungsi cukup baik tetapi saya pikir menggunakan pengecualian dengan cara itu tidak terasa benar bagi saya.
Pembaruan2:
Dimodifikasi untuk lulus jenis daripada menggunakan obat generik:
public static bool Is(this string input, Type targetType)
{
try
{
TypeDescriptor.GetConverter(targetType).ConvertFromString(input);
return true;
}
catch
{
return false;
}
}
protected Boolean TryParse<T>(Object value, out T result) { result = default(T); var convertor = TypeDescriptor.GetConverter(typeof(T)); if (convertor == null || !convertor.IsValid(value)) { return false; } result = (T)convertor.ConvertFrom(value); return true; }
ConvertFrom(value)
metode dalamtry-catch
blok untuk menangkap pengecualianJawaban:
Anda harus menggunakan kelas TypeDescriptor :
sumber
Saya juga membutuhkan TryParse generik baru-baru ini. Inilah yang saya pikirkan;
Maka itu hanya masalah memanggil demikian:
sumber
T
dari handler, dan kita harus secara eksplisit menentukanT
kapan kita menyebutnya. Saya ingin tahu, mengapa itu tidak bisa disimpulkanT
?SomeMethod(TryParse<int>(DollarTextbox.Text, int.TryParse))
tanpa membuat variabel output untuk menangkap hasilnyaint.TryParse
. Namun, saya setuju dengan sentimen Nick tentang memiliki fungsi menyimpulkan tipe.Menggunakan coba / tangkap untuk kontrol aliran adalah kebijakan yang mengerikan. Melempar pengecualian menyebabkan kelambatan kinerja sementara runtime bekerja di sekitar pengecualian. Alih-alih memvalidasi data sebelum mengonversi.
sumber
converter != null
selalu benar, sehingga dapat dihapus dari kode.Jika Anda menggunakan TryParse, Anda dapat menggunakan refleksi dan melakukannya seperti ini:
sumber
Type.GetType(string.Format(...))
dengantype.MakeByRefType()
.Ini menggunakan konstruktor statis untuk setiap jenis generik, sehingga hanya perlu melakukan pekerjaan mahal saat pertama kali Anda menyebutnya pada jenis tertentu. Ini menangani semua jenis dalam namespace sistem yang memiliki metode TryParse. Ini juga bekerja dengan versi nullable dari masing-masing (yang merupakan struct) kecuali untuk enumerasi.
sumber
Bagaimana dengan sesuatu yang seperti ini?
http://madskristensen.net/post/Universal-data-type-checker.aspx ( Arsip )
Ini dapat dikonversi menjadi metode generik dengan mudah.
sumber
catch { }
. Namun, dalam hal ini tidak ada alternatif, karena .NETBaseNumberConverter
melemparException
kelas dasar jika terjadi kesalahan konversi. Ini sangat disayangkan. Bahkan masih ada beberapa tempat dimana jenis pangkalan ini dilempar. Semoga Microsoft akan memperbaikinya dalam versi kerangka kerja yang akan datang.Anda tidak dapat melakukannya pada tipe umum.
Apa yang bisa Anda lakukan adalah membuat antarmuka ITryParsable dan menggunakannya untuk tipe kustom yang mengimplementasikan antarmuka ini.
Saya kira Anda berniat untuk menggunakan ini dengan tipe dasar seperti
int
danDateTime
. Anda tidak dapat mengubah jenis ini untuk mengimplementasikan antarmuka baru.sumber
dynamic
kata kunci, karena itu tidak akan berfungsi pada pengetikan statis. Anda dapat membuat objek dinamis Anda sendiri yang bisa menangani ini, tetapi itu bukan default.Terinspirasi oleh solusi yang diposting di sini oleh Charlie Brown, saya membuat TryParse generik menggunakan refleksi yang secara opsional menampilkan nilai yang diuraikan:
Ini bisa disebut sebagai:
Pembaruan:
Juga berkat solusi YotaXP yang sangat saya sukai, saya membuat versi yang tidak menggunakan metode ekstensi tetapi masih memiliki singleton, meminimalkan kebutuhan untuk melakukan refleksi:
Sebut saja seperti ini:
sumber
Agak terlambat ke pesta, tapi inilah yang saya pikirkan. Tanpa pengecualian, pantulan satu kali (per jenis).
Kelas tambahan diperlukan karena metode ekstensi tidak diizinkan di dalam kelas generik. Ini memungkinkan penggunaan sederhana, seperti yang ditunjukkan di bawah ini, dan hanya hits refleksi saat pertama kali suatu jenis digunakan.
sumber
Ini pilihan lain.
Saya menulis sebuah kelas yang memudahkan untuk mendaftarkan sejumlah
TryParse
penangan. Ini memungkinkan saya melakukan ini:Saya
42
dicetak ke konsol.Kelasnya adalah:
sumber
Ketika saya ingin melakukan hampir hal yang tepat ini, saya harus menerapkannya dengan cara yang keras, mengingat refleksi. Diberikan
T
, merenungkantypeof(T)
dan mencari suatuTryParse
atauParse
metode, memohonnya jika Anda telah menemukannya.sumber
Ini usaha saya. Saya melakukannya sebagai "latihan". Saya mencoba membuatnya mirip dengan yang digunakan sebagai " Convert.ToX () " yang sudah ada - dll. Tapi ini adalah metode ekstensi:
sumber
TypeConverter.ConvertFrom()
ini adalah bahwa kelas sumber harus menyediakan konversi tipe, yang umumnya berarti Anda tidak dapat mendukung konversi ke tipe kustom.Seperti yang Anda katakan,
TryParse
bukan bagian dari antarmuka. Ini juga bukan anggota dari kelas dasar yang diberikan karena sebenarnyastatic
danstatic
fungsi tidak bisavirtual
. Jadi, kompiler tidak memiliki cara untuk memastikan bahwaT
sebenarnya memiliki anggota yang dipanggilTryParse
, jadi ini tidak berfungsi.Seperti yang dikatakan @Mark, Anda dapat membuat antarmuka sendiri dan menggunakan jenis khusus, tetapi Anda kurang beruntung untuk jenis bawaan.
sumber
sumber
Ini adalah pertanyaan tentang 'kendala umum'. Karena Anda tidak memiliki antarmuka spesifik maka Anda macet kecuali Anda mengikuti saran dari jawaban sebelumnya.
Untuk dokumentasi tentang ini, periksa tautan berikut:
http://msdn.microsoft.com/en-us/library/ms379564(VS.80).aspx
Ini menunjukkan kepada Anda bagaimana menggunakan batasan-batasan ini dan harus memberi Anda lebih banyak petunjuk.
sumber
Dipinjam dari http://blogs.msdn.com/b/davidebb/archive/2009/10/23/using-c-dynamic-to-call-static-members.aspx
ketika mengikuti referensi ini: Bagaimana memanggil metode statis di C # 4.0 dengan tipe dinamis?
Dan gunakan sebagai berikut:
sumber
Saya berhasil mendapatkan sesuatu yang berfungsi seperti ini
Ini kode saya
StaticMembersDynamicWrapper diadaptasi dari artikel David Ebbo (itu melontarkan AmbiguousMatchException)
sumber
sumber
Dengan
TypeDescriptor
penggunaan kelasTryParse
terkait:sumber
Menggunakan informasi di atas, inilah yang saya kembangkan. Itu akan mengkonversi objek secara langsung adalah mungkin, jika tidak akan mengkonversi objek ke string dan memanggil metode TryParse untuk jenis objek yang diinginkan.
Saya cache metode dalam kamus karena masing-masing ditemui untuk mengurangi metode pengambilan beban.
Mungkin untuk menguji apakah objek dapat langsung dikonversi ke jenis target, yang selanjutnya akan mengurangi bagian konversi string. Tapi saya akan meninggalkan itu untuk saat ini.
sumber
Saya mengumpulkan banyak ide di sini bersama dan berakhir dengan solusi yang sangat singkat.
Ini adalah metode ekstensi pada string
Saya membuatnya dengan cetakan kaki yang sama dengan metode TryParse pada tipe numerik
''
sumber
T.TryParse ... mengapa?
Saya melihat tidak ada manfaatnya memiliki
TryParse
fungsi generik seperti itu . Ada terlalu banyak strategi berbeda untuk mem-parsing dan mengonversi data di antara berbagai tipe, dengan kemungkinan perilaku yang saling bertentangan. Bagaimana fungsi ini bisa tahu strategi mana yang harus dipilih dalam mode bebas konteks?Convert.ChangeType
. API ini dapat dikustomisasi saat runtime. Apakah fungsi Anda memerlukan perilaku default atau memungkinkan penyesuaian?sumber
Versi untuk mendapatkan keturunan dari XDocument.
sumber