Perbedaan antara casting dan menggunakan metode Convert.To ()

91

Saya memiliki fungsi yang melemparkan doublepada stringnilai-nilai.

string variable = "5.00"; 

double varDouble = (double)variable;

Perubahan kode telah diperiksa dan proyek dibangun dengan kesalahan: System.InvalidCastException: Specified cast is not valid.

Namun, setelah melakukan hal berikut ...

string variable = "5.00"; 

double varDouble = Convert.ToDouble(variable);

... proyek ini dibangun tanpa kesalahan.

Apa perbedaan antara casting dan Convert.To()metode? Mengapa casting melempar Exceptiondan menggunakan Convert.To()tidak?


sumber
6
Berkenaan dengan pertanyaan yang direferensikan , OP menanyakan kapan harus menggunakan cast atau convert, dan jawaban yang diterima menyatakan, "Ini benar-benar masalah pilihan mana pun yang Anda gunakan." Saya menanyakan perbedaan antara pemeran vs petobat. Menurut pendapat saya, jawaban di bawah (pujian SO!) Memberikan lebih banyak detail tentang perbedaan vs. "menggunakan ini atau itu berdasarkan pilihan" ... dan detail ini dapat digunakan untuk membuat pilihan yang lebih tepat, pada dasarnya.
@ edmastermind29 tidak banyak perbedaan antara "apa perbedaan antara x dan y" dan "kapan harus menggunakan x dan y" dalam konteks pemrograman. Keduanya saling menjawab.
nawfal
2
Hampir 3 tahun kemudian, tampaknya tidak ada yang saling menjawab dalam kasus ini. T: "Apa perbedaan antara X dan Y?" J: "Ini benar-benar masalah pilihan mana saja yang Anda gunakan." Tidak terlalu berguna.
Sepertinya tidak ada yang memiliki jawaban langsung yang Berkinerja terbaik juga merupakan bagian dari pertanyaan, Dari pengalaman saya, saya melihat Cast lebih baik terutama dalam mendapatkan nilai kolom seperti ini .. (int) datatable.Rows [0] [0], jika kita tahu itu 100% int
Sundara Prabu

Jawaban:

127

Bahkan jika Anda mungkin melihatnya sebagai padanan, tujuan mereka sama sekali berbeda. Pertama-tama, mari kita coba mendefinisikan apa itu pemeran:

Transmisi adalah tindakan mengubah entitas dari satu tipe data menjadi yang lain.

Ini sedikit umum dan entah bagaimana setara dengan konversi karena pemeran sering memiliki sintaks yang sama dari konversi sehingga pertanyaannya adalah kapan pemeran (implisit atau eksplisit) diizinkan oleh bahasa dan kapan Anda harus menggunakan ( lebih) konversi eksplisit?

Izinkan saya menggambar garis sederhana di antara mereka. Secara formal (bahkan jika setara untuk sintaks bahasa) cast akan mengubah jenis sementara konversi akan / dapat mengubah nilai (akhirnya bersama dengan jenis). Juga pemeran dapat dibalik sementara konversi mungkin tidak.

Topik ini sangat luas jadi mari kita coba mempersempitnya sedikit dengan mengecualikan operator cast kustom dari game.

Pemeran implisit

Dalam C #, cast tersirat ketika Anda tidak akan kehilangan informasi apa pun (harap dicatat bahwa pemeriksaan ini dilakukan dengan tipe dan bukan dengan nilai sebenarnya ).

Tipe primitif

Sebagai contoh:

int tinyInteger = 10;
long bigInteger = tinyInteger;

float tinyReal = 10.0f;
double bigReal = tinyReal;

Pemeran ini tersirat karena selama konversi Anda tidak akan kehilangan informasi apa pun (Anda hanya membuat jenisnya lebih luas). Sebaliknya, cast implisit tidak diizinkan karena, terlepas dari nilai sebenarnya (karena hanya dapat diperiksa pada waktu proses), selama konversi Anda mungkin kehilangan beberapa informasi. Misalnya, kode ini tidak dapat dikompilasi karena a doublemay berisi (dan sebenarnya memang demikian) nilai yang tidak dapat direpresentasikan dengan float:

// won't compile!
double bigReal = Double.MaxValue;
float tinyReal = bigReal;

Objek

Dalam kasus objek (penunjuk ke) cast selalu implisit ketika compiler dapat memastikan bahwa tipe sumber adalah kelas turunan (atau mengimplementasikan) jenis kelas target, misalnya:

string text = "123";
IFormattable formattable = text;

NotSupportedException derivedException = new NotSupportedException();
Exception baseException = derivedException;

Dalam hal ini compiler tahu bahwa stringalat IFormattabledan bahwa NotSupportedExceptionadalah (atau diperoleh dari) Exceptionsehingga pemain tersirat. Tidak ada informasi yang hilang karena objek tidak mengubah tipenya (ini berbeda dengan structtipe s dan primitif karena dengan cast Anda membuat objek baru dari tipe lain ), yang berubah adalah pandangan Anda terhadapnya.

Pemeran eksplisit

Sebuah cast eksplisit ketika konversi tidak dilakukan secara implisit oleh compiler dan kemudian Anda harus menggunakan operator cast. Biasanya itu berarti:

  • Anda mungkin kehilangan informasi atau data sehingga Anda harus menyadarinya.
  • Konversi mungkin gagal (karena Anda tidak dapat mengonversi satu jenis ke jenis lainnya) jadi, sekali lagi, Anda harus menyadari apa yang Anda lakukan.

Tipe primitif

Cast eksplisit diperlukan untuk tipe primitif ketika selama konversi Anda mungkin kehilangan beberapa data, misalnya:

double precise = Math.Cos(Math.PI * 1.23456) / Math.Sin(1.23456);
float coarse = (float)precise;

float epsilon = (float)Double.Epsilon;

Dalam kedua contoh tersebut, meskipun nilainya berada dalam floatkisaran, Anda akan kehilangan informasi (dalam hal ini presisi) sehingga konversinya harus eksplisit. Sekarang coba ini:

float max = (float)Double.MaxValue;

Konversi ini akan gagal jadi, sekali lagi, harus eksplisit sehingga Anda menyadarinya dan Anda dapat melakukan pemeriksaan (dalam contoh, nilainya konstan tetapi mungkin berasal dari beberapa penghitungan run-time atau I / O). Kembali ke contoh Anda:

// won't compile!
string text = "123";
double value = (double)text;

Ini tidak dapat dikompilasi karena kompilator tidak dapat mengubah teks menjadi angka. Teks dapat berisi karakter apa pun, bukan hanya angka dan ini terlalu banyak, di C #, bahkan untuk pemeran eksplisit (tetapi mungkin diizinkan dalam bahasa lain).

Objek

Konversi dari pointer (ke objek) mungkin gagal jika tipenya tidak terkait, misalnya kode ini tidak akan dikompilasi (karena kompilator tahu tidak ada kemungkinan konversi):

// won't compile!    
string text = (string)AppDomain.Current;
Exception exception = (Exception)"abc";

Kode ini akan dikompilasi tetapi mungkin gagal saat run-time (tergantung pada jenis objek yang dicor) dengan InvalidCastException:

object obj = GetNextObjectFromInput();
string text = (string)obj;

obj = GetNextObjectFromInput();
Exception exception = (Exception)obj;

Konversi

Jadi, akhirnya, jika pemain adalah konversi lalu mengapa kita membutuhkan kelas seperti itu Convert? Mengabaikan perbedaan halus yang berasal dari Convertimplementasi dan IConvertibleimplementasi sebenarnya karena di C # dengan cast yang Anda katakan kepada compiler:

percayalah, tipe ini adalah tipe itu bahkan jika Anda tidak dapat mengetahuinya sekarang, biarkan saya melakukannya dan Anda akan melihatnya.

-atau-

jangan khawatir, saya tidak peduli jika sesuatu akan hilang dalam pertobatan ini.

Untuk hal lain, operasi yang lebih eksplisit diperlukan (pikirkan tentang implikasi cast yang mudah , itulah mengapa C ++ memperkenalkan sintaks yang panjang, verbose, dan eksplisit untuk mereka). Ini mungkin melibatkan operasi yang kompleks (untuk string-> doublekonversi diperlukan penguraian). Konversi ke string, misalnya, selalu memungkinkan (melalui ToString()metode) tetapi itu mungkin berarti sesuatu yang berbeda dari yang Anda harapkan sehingga harus lebih eksplisit daripada pemeran ( lebih banyak Anda menulis, lebih banyak Anda memikirkan apa yang Anda lakukan ).

Konversi ini dapat dilakukan di dalam objek (menggunakan instruksi IL yang diketahui untuk itu), menggunakan operator konversi kustom (ditentukan di kelas yang akan ditransmisikan) atau mekanisme yang lebih kompleks ( TypeConverters atau metode kelas, misalnya). Anda tidak mengetahui apa yang akan terjadi untuk melakukan itu tetapi Anda sadar itu mungkin gagal (itulah mengapa IMO ketika konversi yang lebih terkontrol dimungkinkan, Anda harus menggunakannya). Dalam kasus Anda, konversi hanya akan mengurai stringmenjadi double:

double value = Double.Parse(aStringVariable);

Tentu saja ini mungkin gagal jadi jika Anda melakukannya, Anda harus selalu menangkap pengecualian yang mungkin dilontarkan ( FormatException). Ini di luar topik di sini tetapi ketika a TryParsetersedia maka Anda harus menggunakannya (karena secara semantik Anda mengatakan itu mungkin bukan angka dan bahkan lebih cepat ... gagal).

Konversi dalam .NET dapat berasal dari banyak tempat TypeConverter,,, pemeran implisit / eksplisit dengan operator konversi yang ditentukan pengguna, implementasi IConvertibledan metode parsing (apakah saya lupa sesuatu?). Lihat MSDN untuk detail lebih lanjut tentang mereka.

Untuk menyelesaikan jawaban panjang ini, hanya beberapa kata tentang operator konversi yang ditentukan pengguna. Hanya gula untuk membiarkan programmer menggunakan pemeran untuk mengubah satu jenis ke jenis lainnya. Ini adalah metode di dalam kelas (yang akan dicor) yang mengatakan "hei, jika dia ingin mengubah tipe ini ke tipe itu maka saya bisa melakukannya". Sebagai contoh:

float? maybe = 10; // Equals to Nullable<float> maybe = 10;
float sure1 = (float)maybe; // With cast
float sure2 = maybe.Value; // Without cast

Dalam hal ini eksplisit karena mungkin gagal tetapi ini dibiarkan untuk implementasi (meskipun ada pedoman tentang ini). Bayangkan Anda menulis kelas string kustom seperti ini:

EasyString text = "123"; // Implicit from string
double value = (string)text; // Explicit to double

Dalam implementasi Anda, Anda mungkin memutuskan untuk "membuat hidup programmer lebih mudah" dan mengekspos konversi ini melalui cast (ingat itu hanya jalan pintas untuk menulis lebih sedikit). Beberapa bahasa bahkan mungkin mengizinkan ini:

double value = "123";

Mengizinkan konversi implisit ke jenis apa pun (pemeriksaan akan dilakukan pada waktu proses). Dengan opsi yang tepat ini dapat dilakukan, misalnya, di VB.NET. Itu hanya filosofi yang berbeda.

Apa yang dapat saya lakukan dengan mereka?

Jadi pertanyaan terakhir adalah kapan Anda harus menggunakan satu atau lainnya. Mari kita lihat kapan Anda dapat menggunakan pemeran eksplisit:

  • Konversi antara jenis dasar.
  • Konversi dari objectke jenis lain (ini mungkin termasuk membuka kemasan juga).
  • Konversi dari kelas turunan ke kelas dasar (atau ke antarmuka yang diimplementasikan).
  • Konversi dari satu jenis ke jenis lainnya melalui operator konversi kustom.

Hanya konversi pertama yang dapat dilakukan, Convertjadi untuk yang lain Anda tidak punya pilihan dan Anda perlu menggunakan pemeran eksplisit.

Mari kita lihat sekarang kapan Anda dapat menggunakan Convert:

  • Konversi dari jenis dasar apa pun ke jenis dasar lain (dengan beberapa batasan, lihat MSDN ).
  • Konversi dari jenis apa pun yang diterapkan IConvertibleke jenis lain (didukung).
  • Konversi dari / ke bytelarik ke / dari string.

Kesimpulan

IMO Convertharus digunakan setiap kali Anda mengetahui konversi mungkin gagal (karena formatnya, karena rentangnya atau karena mungkin tidak didukung), bahkan jika konversi yang sama dapat dilakukan dengan cast (kecuali ada hal lain yang tersedia). Ini menjelaskan siapa yang akan membaca kode Anda apa maksud Anda dan bahwa kode itu mungkin gagal (menyederhanakan debug).

Untuk semua hal lain Anda perlu menggunakan pemeran, tidak ada pilihan, tetapi jika metode lain yang lebih baik tersedia maka saya sarankan Anda menggunakannya. Dalam contoh Anda, konversi dari stringke doubleadalah sesuatu yang (terutama jika teks berasal dari pengguna) sering kali akan gagal, jadi Anda harus membuatnya sedetail mungkin (selain itu Anda mendapatkan kontrol lebih besar), misalnya menggunakan TryParsemetode.

Sunting: apa perbedaan di antara mereka?

Menurut pertanyaan yang diperbarui dan menyimpan apa yang saya tulis sebelumnya (tentang kapan Anda dapat menggunakan pemeran dibandingkan dengan kapan Anda dapat / harus menggunakan Convert) maka poin terakhir yang harus diperjelas adalah jika ada perbedaan di antara mereka (apalagi Convertpenggunaan IConvertibledan IFormattableantarmuka sehingga dapat melakukan operasi tidak diperbolehkan dengan gips).

Jawaban singkatnya adalah ya, mereka berperilaku berbeda . Saya melihat Convertkelas seperti kelas metode penolong begitu sering memberikan beberapa manfaat atau perilaku yang sedikit berbeda. Sebagai contoh:

double real = 1.6;
int castedInteger = (int)real; // 1
int convertedInteger = Convert.ToInt32(real); // 2

Sangat berbeda, bukan? Cast memotong (itulah yang kita semua harapkan) tetapi Convertmelakukan pembulatan ke integer terdekat (dan ini mungkin tidak diharapkan jika Anda tidak menyadarinya). Setiap metode konversi memperkenalkan perbedaan sehingga aturan umum tidak dapat diterapkan dan harus dilihat kasus per kasus ... 19 jenis dasar untuk dikonversi ke setiap jenis lainnya ... daftar bisa sangat panjang, jauh lebih baik untuk berkonsultasi kasus MSDN dengan kasus!

Adriano Repetti
sumber
Saya mengubah pertanyaan menjadi Difference between casting and using the Convert.To() method,. Jika tidak, jawaban yang sangat komprehensif. (Saya harap pertanyaan saya dibuka kembali ...)
@ edmastermind29 Saya mengedit sedikit pertanyaan, topiknya terlalu panjang bahkan untuk jawaban yang panjang (300+ kemungkinan konversi ke daftar). Convert menambahkan manfaat (atau hanya perilaku tak terduga?) Tidak hanya vs cast tetapi vs antarmuka IConvertible dan IFormattable "biasa" juga.
Adriano Repetti
Saya tidak suka gagasan yang dipinjam dari C bahwa doublenilai - nilai yang tidak mewakili bilangan bulat harus "dapat diubah" int. Sebuah cor akan tampak paradigma yang tepat dalam kasus di mana misalnya seseorang mengambil Int32nilai dari double[]yang memegang campuran bilangan real dan Int32nilai yang telah diubah menjadi double[upaya untuk mengubah nilai yang tidak dapat direpresentasikan secara tepat di int32akan menunjukkan kondisi yang tidak terduga dan harus memicu pengecualian], tetapi saya akan berpikir bahwa ketika seseorang menginginkan konversi yang merugikan, dia harus spesifik tentang bentuk yang diinginkannya.
supercat
1
Perbedaan lainnya adalah dari objek ke tipe primitif. misalnyaobject o = 123; var l = Convert.ToInt64(o); var i = (long) (int) o; var f = (long) o // InvalidCastException
yue shi
1
@ rory.ap itu poin penting. Tidak, secara formal itu bukan cast ( float-> int) tapi paksaan . Seorang pemeran mungkin misalnya DerivedClass-> BaseClass. Ini membingungkan karena karena di C # kita menggunakan kata yang sama (dan operator) untuk keduanya tetapi sebenarnya keduanya berbeda. Definisi formal untuk membedakan mereka sedikit lebih rumit daripada yang saya tulis.
Adriano Repetti
13

Mentransmisikan adalah cara untuk memberi tahu kompiler, "Saya tahu Anda mengira bahwa variabel ini adalah Bar, tetapi kebetulan saya tahu lebih banyak daripada Anda; objek sebenarnya adalah Foo, jadi izinkan saya memperlakukannya seolah-olah itu adalah Foo dari sekarang." Kemudian, pada saat runtime, jika objek sebenarnya ternyata benar-benar Foo maka kode Anda berfungsi, jika ternyata objek tersebut sama sekali bukan Foo, Anda akan mendapatkan pengecualian. (Secara khusus System.InvalidCastException.)

Mengonversi di sisi lain adalah cara untuk mengatakan, "Jika Anda memberi saya sebuah objek tipe Bar, saya bisa membuat objek Foo baru yang mewakili apa yang ada di objek Bar itu. Saya tidak akan mengubah objek aslinya, itu tidak akan '' t memperlakukan objek asli secara berbeda, itu akan menciptakan sesuatu yang baru yang hanya didasarkan pada beberapa nilai lain . Mengenai bagaimana melakukannya, itu bisa menjadi apa saja. Dalam kasus Convert.ToDoubleitu akan berakhir dengan memanggilDouble.Parseyang memiliki semua jenis logika kompleks untuk menentukan jenis string apa yang mewakili nilai numerik apa. Anda dapat menulis metode konversi Anda sendiri yang memetakan string menjadi dua kali lipat secara berbeda (mungkin untuk mendukung beberapa konvensi yang sama sekali berbeda untuk menampilkan angka, seperti angka romawi atau apa pun). Sebuah konversi bisa melakukan apa saja, tetapi idenya adalah Anda tidak benar-benar meminta kompilator untuk melakukan apa pun untuk Anda; Anda adalah orang yang menulis kode untuk menentukan cara membuat objek baru karena kompiler, tanpa bantuan Anda, tidak memiliki cara untuk mengetahui cara memetakan (sebagai contoh) a stringke a double.

Jadi, kapan Anda mengonversi, dan kapan Anda melakukan cast? Dalam kedua kasus kita memiliki beberapa variabel tipe, katakanlah A, dan kita ingin memiliki variabel tipe B. Jika objek A kita benar-benar, di bawah tenda, adalah B, maka kita melemparkan. Jika bukan benar-benar B, maka kita perlu mengubahnya, dan menentukan bagaimana program seharusnya mendapatkan B dari A.

Pelayanan
sumber
Dalam salah satu posting SO Eric Lippert menyebutkan bahwa tidak ada yang disebut pemeran implisit dan itu adalah konversi implisit . Saya telah menggunakan pemeran dan konversi secara bergantian. apa yang salah dengan mengatakan "pemeran implisit"? Bukankah jika konversi tersirat tanpa memerlukan pemeran apapun, orang dapat mengatakan itu adalah "pemeran implisit"?
rahulaga_dev
1
@RahulAgarwal Apa itu pemeran adalah operasi di mana Anda perlu secara eksplisit menunjukkan bahwa tipe yang diberikan adalah (atau dapat dibuat menjadi) contoh valid dari tipe lain. Jika ada konversi implisit, tidak ada cast yang diperlukan untuk memperlakukan tipe sebagai tipe lain. Jadi mengatakan "pemeran implisit" tidak benar-benar masuk akal (kecuali untuk kemungkinan beberapa situasi seperti yang Eric sebutkan di mana operator transmisi ditambahkan tanpa pengembang mengetiknya, seperti saat menggunakan a foreach). Di luar pengecualian tersebut, menurut definisi , pemeran adalah eksplisit.
Pelayanan
6

Dari MSDN:

Konversi eksplisit (cast): Konversi eksplisit membutuhkan operator cast. Transmisi diperlukan ketika informasi mungkin hilang dalam konversi, atau ketika konversi mungkin tidak berhasil karena alasan lain. Contoh umum termasuk konversi numerik ke jenis yang memiliki presisi kurang atau rentang lebih kecil, dan konversi instance kelas dasar ke kelas turunan.

Perhatikan contoh berikut:

double a = 2548.3;
int b;
b = (int)a; //2548 --> information (.3) lost in the conversion

Dan juga:

Cast adalah cara untuk memberi tahu compiler secara eksplisit bahwa Anda bermaksud melakukan konversi dan Anda sadar bahwa kehilangan data mungkin terjadi.

Anda dapat menggunakan System.Convertkelas ketika Anda ingin mengonversi antara jenis yang tidak kompatibel . Perbedaan utama antara casting dan convert adalah kompilasi dan run-time . Pengecualian konversi jenis muncul pada saat run-time , yaitu jenis cast yang gagal saat run-time akan menyebabkan InvalidCastExceptionpelemparan.


Kesimpulan: Dalam casting Anda memberi tahu kompiler yang abenar-benar mengetik bdan jika demikian proyek tersebut dibangun tanpa kesalahan seperti contoh ini:

double s = 2;
int a = (int) s;

Namun dalam konversi Anda katakan untuk compiler ada cara untuk membuat objek baru dari ajenis b, silakan melakukannya dan proyek membangun tanpa kesalahan tapi seperti yang saya katakan jika jenis cor gagal pada saat run-time, itu akan menyebabkan InvalidCastExceptionke dilempar .

Misalnya kode di bawah ini tidak pernah dikompilasi karena compiler mendeteksi yang tidak dapat menampilkan ekspresi tipe DateTimeke tipe int:

DateTime s = DateTime.Now;
int a = (int)(s);

Tapi yang ini berhasil dikompilasi:

DateTime s = DateTime.Now;
int a = Convert.ToInt32(s);

Tetapi pada saat run-time Anda akan mendapatkan InvalidCastExceptionyang mengatakan:

Pemeran tidak valid dari 'DateTime' hingga 'Int32'.

Salah Akbari
sumber
4

Dalam contoh Anda, Anda mencoba mentransmisikan string menjadi ganda (tipe non integral).

Konversi eksplisit diperlukan agar dapat berfungsi.

Dan saya harus menunjukkan bahwa Anda dapat menggunakan Convert.ToDoublesebagai pengganti Convert.ToInt64karena Anda dapat kehilangan bagian pecahan dari nilai ganda saat Anda mengonversi ke int.

jika variabel Anda memiliki nilai "5.25" varDouble akan menjadi 5,00 (kehilangan 0,25 karena Konversi ke Int64)

Untuk menjawab pertanyaan Anda tentang transmisi vs konversi.

Pemeran Anda (pemeran eksplisit) tidak memenuhi persyaratan untuk pemeran eksplisit. nilai yang Anda coba tuang dengan operator cor tidak valid (yaitu, tidak terpisahkan).

Kunjungi Halaman MSDN ini untuk mengetahui aturan casting / konversi

bajingan
sumber
@ edmastermind29 Saya telah memperbarui jawaban saya. saya harap ini menjawab pertanyaan Anda.
scartag
Apa persyaratan untuk pemeran eksplisit ... yang terkait dengan pertanyaan saya? Apakah ini berkaitan dengan nilai "non integral"?
@ edmaster.Ya. jika nilai yang Anda coba masukkan ke jenis numerik adalah non-numerik, transmisi tidak valid .. diperlukan konversi.
scartag
4

The Convert.DoubleMetode sebenarnya hanya secara internal memanggil Double.Parse(string)metode.

Baik Stringtype maupun type tidak Doublemenentukan konversi eksplisit / implisit antara kedua jenis tersebut, jadi transmisi akan selalu gagal.

The Double.ParseMetode akan melihat masing-masing karakter dalam stringdan membangun nilai numerik berdasarkan pada nilai-nilai karakter dalam string. Jika salah satu karakter tidak valid, Parsemetode gagal (menyebabkan Convert.Doublemetode gagal juga).

Dan
sumber
1
Dan bagaimana ini berbeda dari pemeran eksplisit?
3
Pemeran eksplisit tidak melihat apa tipe datanya, itu hanya melihat byte. Contoh akan mentransmisikan char x = '1' ke integer, integer akan menjadi 49 karena karakter '1' adalah # 49 dalam tabel ascii
user1751547
@ user1751547 Jadi, akankah pengguna Convert.ToDouble()melihat melampaui byte dan mempertimbangkan datanya?
@ user1751547 Saya pikir itulah jenis intuisi yang diperlukan dalam menjawab pertanyaan ini dengan benar. Hanya mengatakan "itu tidak ditentukan" adalah sedikit diperdebatkan.
Ant P
@ edmastermind29 Ya, itu akan melihat jenis input, dan jika itu adalah string itu akan melewati setiap karakter, mengetahui bahwa jika nilai ascii char adalah 49, maka itu adalah karakter '1' dan mengubahnya dengan benar
user1751547
3

Transmisi tidak melibatkan konversi apa pun, yaitu representasi internal dari suatu nilai tidak berubah. Contoh:

object o = "Hello"; // o is typed as object and contains a string.
string s = (string)o; // This works only if o really contains a string or null.

Anda dapat mengkonversi doubleke stringseperti ini

double d = 5;
string s = d.ToString(); // -> "5"

// Or by specifying a format
string formatted = d.ToString("N2"); // -> "5.00"

Anda dapat mengonversi a stringke a doubledengan beberapa cara (di sini hanya dua cara):

string s = "5";
double d = Double.Parse(s); // Throws an exception if s does not contain a valid number

Atau cara yang aman

string s = "5";
double d;
if (Double.TryParse(s, out d)) {
    Console.WriteLine("OK. Result = {0}", d);
} else {
    Console.WriteLine("oops!");
}
Olivier Jacot-Descombes
sumber
Convert.ToDouble()panggilan internalDouble.Parse() . Apakah menguntungkan saya untuk menggunakan Convert.ToDouble()berlebihan Double.Parse()atau tidak dan mengapa?
Convert.ToDoublememiliki banyak kelebihan beban yang menerima berbagai jenis masukan. Overload menerima stringkembali 0.0jika sebuah nullstring dilewatkan. Selain itu, saya tidak melihat keuntungan dalam menggunakannya.
Olivier Jacot-Descombes
Jadi, apakah atau ... atau Double.Parse()ada sesuatu untuk ditawarkan yang harus saya pertimbangkan?
Double.Parse()lebih langsung dari Convert.ToDouble(). Jika Anda yakin bahwa string Anda akan berisi nomor yang valid, Anda dapat menggunakannya dengan aman, jika tidak, saya sarankan Anda untuk menggunakannya Double.TryParse.
Olivier Jacot-Descombes
1
string variable = "5.00";     
double varDouble = (double)variable;

Konversi di atas tidak diizinkan oleh bahasa. Berikut adalah daftar cast eksplisit untuk tipe numerik: http://msdn.microsoft.com/en-us/library/yht2cx7b.aspx Seperti yang Anda lihat, bahkan tidak setiap tipe numerik dapat dikonversi ke tipe numerik lain

Beberapa info lebih lanjut tentang transmisi di sini

Dan apa perbedaannya dengan Convert.ToDouble ()?

Saat Anda mentransmisikan suatu tipe, struktur data tidak berubah. Nah, dalam hal konversi nilai numerik, Anda mungkin kehilangan beberapa bit atau mendapatkan beberapa bit tambahan. Tapi Anda masih bekerja dengan angka.Anda hanya mengubah jumlah memori yang diambil oleh nomor itu. Itu cukup aman bagi kompiler untuk melakukan semua yang diperlukan.

Tetapi ketika Anda mencoba untuk mentransmisikan string ke sebuah angka, Anda tidak dapat melakukannya karena itu tidak cukup untuk mengubah jumlah memori yang diambil oleh variabel. Misalnya, 5.00sebagai string adalah urutan "angka": 53 (5) 46 (.) 48 (0) 48 (0) - itu untuk ASCII, tetapi string akan berisi sesuatu yang serupa. Jika kompiler hanya akan mengambil N (4 untuk double? Tidak yakin) byte pertama dari string - potongan itu akan berisi nomor ganda yang sama sekali berbeda. Pada saat yang sama Convert.ToDouble () menjalankan algoritma khusus yang akan mengambil setiap simbol dari sebuah string, mencari digit yang diwakilinya dan membuat angka ganda untuk Anda, jika string mewakili sebuah angka. Bahasa seperti PHP, secara kasar, akan memanggil Convert.ToDouble untuk Anda di latar belakang. Tetapi C #, seperti bahasa yang diketik secara statis, tidak akan melakukannya untuk Anda. Ini memungkinkan Anda untuk memastikan bahwa operasi apa pun adalah jenis yang aman dan Anda tidak akan mendapatkan sesuatu yang tidak terduga melakukan sesuatu seperti:

double d = (double)"zzzz"
Viktor S.
sumber
@ edmastermind29 lihat jawaban saya yang diperbarui. Saya sudah mencoba menjelaskannya. Penjelasan jauh dari sempurna, tetapi anggaplah itu menjelaskan perbedaannya.
Viktor S.
1

Mentransmisikan string ke double seperti itu tidak diperbolehkan C # itulah sebabnya Anda mendapatkan Exception, Anda harus mengubah string tersebut ( dokumen MSDN yang menunjukkan jalur konversi yang dapat diterima). Ini hanya karena sebuah string tidak selalu berisi data numerik, tetapi berbagai tipe numerik akan (kecuali nilai null). A Convertakan menjalankan metode yang akan memeriksa string untuk melihat apakah itu dapat diubah menjadi nilai numerik. Jika bisa, maka itu akan mengembalikan nilai itu. Jika tidak bisa, itu akan membuat pengecualian.

Untuk mengubahnya, Anda memiliki beberapa opsi. Anda menggunakan Convertmetode dalam pertanyaan Anda, ada Parseyang sebagian besar mirip dengan Convert, tetapi Anda juga harus melihat TryParse yang memungkinkan Anda melakukan:

string variable = "5.00"; 

double varDouble;

if (Double.TryParse(variable, out varDouble)) {
    //Code that runs if the conversion succeeded.
} else {
    //Code that runs if the conversion failed.
}

Ini menghindari kemungkinan pengecualian jika Anda mencoba Convertatau Parsestring non-numerik.

Tajam
sumber
Apakah menguntungkan saya menggunakan TryParseover Convertkarena TryParsememeriksa apakah konversi berhasil?
@ edmasterind29 Saya rasa begitu. Konversi akan memunculkan pengecualian jika konversi gagal. TryParse akan mengembalikan boolean, True jika konversi berhasil dan False jika gagal.
Tertarik
1

double varDouble = (double)variablemengasumsikan bahwa variablesudah menjadi ganda. Jika variablebukan double (itu string) maka ini akan gagal. double varDouble = Convert.ToDouble(variable)tidak seperti yang dikatakan - itu mengubah. Jika itu dapat mengurai atau mengekstrak ganda dari variablemaka itu akan.

Saya menggunakan kedua Double.Parseatau Double.TryParsekarena lebih jelas menunjukkan apa yang seharusnya terjadi. Anda mulai dengan string dan mengharapkannya dapat diubah menjadi ganda. Jika ada keraguan, gunakan TryParse.

Jika variablemerupakan argumen metode, ubah tipe menjadi ganda. Buat penelepon bertanggung jawab untuk memberikan tipe yang benar. Dengan cara itu kompilator bekerja untuk Anda.

Scott Hannen
sumber
-1

Perbedaan yang paling penting adalah jika tipe casting digunakan dan konversi gagal (katakanlah kita mengonversi nilai float yang sangat besar ke int) tidak ada pengecualian yang akan dilemparkan dan nilai minimum yang dapat ditahan int akan ditampilkan. Tetapi dalam kasus menggunakan Convert , pengecualian akan dilemparkan untuk skenario seperti itu.

TomHardy
sumber