Saya memiliki fungsi yang melemparkan double
pada string
nilai-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 Exception
dan menggunakan Convert.To()
tidak?
Jawaban:
Bahkan jika Anda mungkin melihatnya sebagai padanan, tujuan mereka sama sekali berbeda. Pertama-tama, mari kita coba mendefinisikan apa itu pemeran:
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
double
may berisi (dan sebenarnya memang demikian) nilai yang tidak dapat direpresentasikan denganfloat
:// 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
string
alatIFormattable
dan bahwaNotSupportedException
adalah (atau diperoleh dari)Exception
sehingga pemain tersirat. Tidak ada informasi yang hilang karena objek tidak mengubah tipenya (ini berbeda denganstruct
tipe 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:
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
float
kisaran, 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 dariConvert
implementasi danIConvertible
implementasi sebenarnya karena di C # dengan cast yang Anda katakan kepada compiler:-atau-
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
->double
konversi diperlukan penguraian). Konversi kestring
, misalnya, selalu memungkinkan (melaluiToString()
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 (
TypeConverter
s 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 menguraistring
menjadidouble
: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 aTryParse
tersedia 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, implementasiIConvertible
dan 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:
object
ke jenis lain (ini mungkin termasuk membuka kemasan juga).Hanya konversi pertama yang dapat dilakukan,
Convert
jadi untuk yang lain Anda tidak punya pilihan dan Anda perlu menggunakan pemeran eksplisit.Mari kita lihat sekarang kapan Anda dapat menggunakan
Convert
:IConvertible
ke jenis lain (didukung).byte
larik ke / dari string.Kesimpulan
IMO
Convert
harus 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
string
kedouble
adalah 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 menggunakanTryParse
metode.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 (apalagiConvert
penggunaanIConvertible
danIFormattable
antarmuka sehingga dapat melakukan operasi tidak diperbolehkan dengan gips).Jawaban singkatnya adalah ya, mereka berperilaku berbeda . Saya melihat
Convert
kelas 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
Convert
melakukan 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!sumber
Difference between casting and using the Convert.To() method
,. Jika tidak, jawaban yang sangat komprehensif. (Saya harap pertanyaan saya dibuka kembali ...)double
nilai - nilai yang tidak mewakili bilangan bulat harus "dapat diubah"int
. Sebuah cor akan tampak paradigma yang tepat dalam kasus di mana misalnya seseorang mengambilInt32
nilai daridouble[]
yang memegang campuran bilangan real danInt32
nilai yang telah diubah menjadidouble
[upaya untuk mengubah nilai yang tidak dapat direpresentasikan secara tepat diint32
akan 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.object o = 123; var l = Convert.ToInt64(o); var i = (long) (int) o; var f = (long) o // InvalidCastException
float
->int
) tapi paksaan . Seorang pemeran mungkin misalnyaDerivedClass
->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.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.ToDouble
itu akan berakhir dengan memanggilDouble.Parse
yang 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) astring
ke adouble
.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.
sumber
foreach
). Di luar pengecualian tersebut, menurut definisi , pemeran adalah eksplisit.Dari
MSDN
:Perhatikan contoh berikut:
double a = 2548.3; int b; b = (int)a; //2548 --> information (.3) lost in the conversion
Dan juga:
Anda dapat menggunakan
System.Convert
kelas 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 menyebabkanInvalidCastException
pelemparan.Kesimpulan: Dalam casting Anda memberi tahu kompiler yang
a
benar-benar mengetikb
dan 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
a
jenisb
, silakan melakukannya dan proyek membangun tanpa kesalahan tapi seperti yang saya katakan jika jenis cor gagal pada saat run-time, itu akan menyebabkanInvalidCastException
ke dilempar .Misalnya kode di bawah ini tidak pernah dikompilasi karena compiler mendeteksi yang tidak dapat menampilkan ekspresi tipe
DateTime
ke tipeint
: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
InvalidCastException
yang mengatakan:sumber
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.ToDouble
sebagai penggantiConvert.ToInt64
karena 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
sumber
The
Convert.Double
Metode sebenarnya hanya secara internal memanggilDouble.Parse(string)
metode.Baik
String
type maupun type tidakDouble
menentukan konversi eksplisit / implisit antara kedua jenis tersebut, jadi transmisi akan selalu gagal.The
Double.Parse
Metode akan melihat masing-masing karakter dalamstring
dan membangun nilai numerik berdasarkan pada nilai-nilai karakter dalamstring
. Jika salah satu karakter tidak valid,Parse
metode gagal (menyebabkanConvert.Double
metode gagal juga).sumber
Convert.ToDouble()
melihat melampaui byte dan mempertimbangkan datanya?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
double
kestring
seperti inidouble d = 5; string s = d.ToString(); // -> "5" // Or by specifying a format string formatted = d.ToString("N2"); // -> "5.00"
Anda dapat mengonversi a
string
ke adouble
dengan 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!"); }
sumber
Convert.ToDouble()
panggilan internalDouble.Parse()
. Apakah menguntungkan saya untuk menggunakanConvert.ToDouble()
berlebihanDouble.Parse()
atau tidak dan mengapa?Convert.ToDouble
memiliki banyak kelebihan beban yang menerima berbagai jenis masukan. Overload menerimastring
kembali0.0
jika sebuahnull
string dilewatkan. Selain itu, saya tidak melihat keuntungan dalam menggunakannya.Double.Parse()
ada sesuatu untuk ditawarkan yang harus saya pertimbangkan?Double.Parse()
lebih langsung dariConvert.ToDouble()
. Jika Anda yakin bahwa string Anda akan berisi nomor yang valid, Anda dapat menggunakannya dengan aman, jika tidak, saya sarankan Anda untuk menggunakannyaDouble.TryParse
.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
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"
sumber
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
Convert
akan 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
Convert
metode dalam pertanyaan Anda, adaParse
yang sebagian besar mirip denganConvert
, 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
Convert
atauParse
string non-numerik.sumber
TryParse
overConvert
karenaTryParse
memeriksa apakah konversi berhasil?double varDouble = (double)variable
mengasumsikan bahwavariable
sudah menjadi ganda. Jikavariable
bukan 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 darivariable
maka itu akan.Saya menggunakan kedua
Double.Parse
atauDouble.TryParse
karena lebih jelas menunjukkan apa yang seharusnya terjadi. Anda mulai dengan string dan mengharapkannya dapat diubah menjadi ganda. Jika ada keraguan, gunakanTryParse
.Jika
variable
merupakan argumen metode, ubah tipe menjadi ganda. Buat penelepon bertanggung jawab untuk memberikan tipe yang benar. Dengan cara itu kompilator bekerja untuk Anda.sumber
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.
sumber