C# ilgisiz tipler arasında kendiliğinden dönüşüm yapmaz. Rakamlar içeren bir string yine bir string'tir ve bir double sessizce int olmaz. Dönüşümü açıkça yaparsınız ve hangi aracı kullanacağınız neyi dönüştürdüğünüze bağlıdır: metinden sayıya (parse etme), bir sayısal tipten diğerine (cast) ya da bir nesneden daha özel bir tipe (as, is).
String'den int'e: Parse, TryParse ve Convert
Metni bir int'e çevirmenin üç standart yolu vardır:
Çıktı:
2500
TryParse ok: 1250
TryParse failed, d = 0
42
-17
int.TryParse bir bool döndürür ve sonucu, başarısızlıkta 0'a ayarlanan bir out değişkenine yazar. Kullanıcının yazdığı her şey için hatalı girdi olağan olduğundan, girdi, dosyalar ve sorgu string'leri için varsayılan seçim TryParse'tır. Aynı metotlar her sayısal tipte vardır: long.TryParse, double.TryParse, decimal.Parse vb.
Her biri hatalı girdiyle ne yapar
Üç metot yalnızca nasıl başarısız olduklarıyla ayrılır:
Çıktı:
int.Parse(null) throws ArgumentNullException
Convert.ToInt32(null) = 0
int.Parse("abc") throws FormatException
int.Parse("12.5") throws FormatException
int.Parse("1,000") throws FormatException
int.Parse("9999999999") throws OverflowException
int.Parse("") throws FormatException
Bir FormatException tanıdık "Input string was not in a correct format" mesajını taşır (.NET 8 ve sonrasında metni tırnak içinde vererek "The input string '12.5' was not in a correct format" der) ve en yaygın C# çalışma zamanı hatalarından biridir: "12.5" bir int değildir, "1,000" de değildir. Bunları kabul etmek için decimal olarak parse edin ya da parser'a hangi stillere izin verildiğini söyleyin:
Çıktı:
1000
255
13
10
Kültür: "1.5" neden 15 olabilir
Parse işlemi varsayılan olarak geçerli kültürü kullanır ve kültürler ayırıcılar konusunda anlaşamaz. Almanca ve birçok başka Avrupa kültüründe ondalık ayırıcı virgüldür ve nokta binlikleri gruplar. Aynı string farklı sayılar verir:
Çıktı:
1.5
15
1.5
Veri dosyalarını, JSON'u, yapılandırmayı ya da makine tarafından üretilen herhangi bir şeyi okuyan kod, hem parse ederken hem biçimlendirirken her zaman CultureInfo.InvariantCulture vermelidir. Aksi halde aynı program bir geliştiricinin bilgisayarında çalışır ve başka bir dile ayarlı bir sunucuda her sayıyı yanlış okur. Geçerli kültürü yalnızca bir insanın yazdığı ya da okuyacağı metin için kullanın.
Örtük ve açık sayısal dönüşümler
Genişleten dönüşümler örtük olarak gerçekleşir: int'ten long'a, int'ten double'a, float'tan double'a, int'ten decimal'e. Değerin büyüklüğünü ya da kesirli kısmını kaybedebilecek bir dönüşüm açık bir (type)value cast'i gerektirir. Akılda tutulacak bir istisna: int ya da long'dan float'a ve long'dan double'a dönüşümler hassasiyet kaybedebilseler de örtüktür: float f = 16_777_217; derlenir ve 16777216 saklar.
Çıktı:
9 -9
10
2
4
705032704
9.99
7 7.0 7
Hatırlanacak üç şey. Kayan noktadan tamsayıya cast keser; yuvarlamaz. Convert.ToInt32(double) bankacı yuvarlamasıyla yuvarlar (yarımlar çift komşuya gider). Ve sığmayan bir tamsayı cast'i, checked bir bağlamda çalışmadıkça sessizce başa sarar; checked bağlamda OverflowException fırlatır (bkz. veri tipleri).
int x = 3.7; bir derleme hatasıdır (CS0266: cannot implicitly convert type 'double' to 'int', an explicit conversion exists); bu, derleyicinin sizden bir cast ile bir yuvarlama metodu arasında seçim yapmanızı istemesidir.
Sayıları ve diğer tipleri string'e çevirmek
Her tipin ToString() metodu vardır ve sayısal tipler bir biçim string'i kabul eder. String interpolation aynı biçimlendirmeyi çağırır:
Çıktı:
42
000042
1234.50
1,234.50
$1,234.50
FF
1010
True
Order 000042: 1234.50
Biçim kodları (D, F, N, C, X, P, E) ve "0.00" gibi özel desenler string interpolation sayfasında ele alınır.
Karakterler ve boolean'lar
Çıktı:
7
55
7
7
A
True
False
1
False
(int)'7' 7 değil, karakterin kodu olan 55'tir. Bu, bir sayının basamaklarını toplayan herkesi yanıltır; '0''ı çıkarın ya da char.GetNumericValue kullanın. bool.Parse herhangi bir harf büyüklüğünde "true" ve "false"'u kabul eder, başka hiçbir şeyi değil ("yes" ve "1" istisna fırlatır).
Referans dönüşümleri: cast, as ve is
Sınıf tipleri için bir cast, nesnenin gerçek tipini çalışma zamanında kontrol eder. Bir temel sınıfa yukarı cast örtüktür. Türetilmiş bir sınıfa aşağı cast ise açık bir cast gerektirir ve nesne başka bir şeyse InvalidCastException fırlatır:
Çıktı:
4242
True
Card ending 4242, 50.00
InvalidCastException
5
cannot unbox int as long
Tipe göre dallanmanız gerektiğinde değişkenli is'i tercih edin; tek bir kontroldür, istisna fırlatamaz ve yeni değişken yalnızca testin başarılı olduğu yerde kapsamdadır. Farklı bir tip, yüksek sesle başarısız olması gereken bir hata olacaksa düz bir cast kullanın. Boxed int durumu, object koleksiyonlarından ya da DataRow hücrelerinden sayı okuyanları yakalar: önce tam tipe unbox edin ((long)(int)boxed) ya da her sayısal tipi ele alan Convert.ToInt64(boxed)'u kullanın.
Sıkça Sorulan Sorular
C#'ta bir string int'e nasıl çevrilir?
Metin bir kullanıcıdan, bir dosyadan ya da ağdan geliyorsa int.TryParse(text, out int number) kullanın: metin geçerli bir sayı değilse istisna fırlatmak yerine false döndürür. Geçersiz metin bir hataysa ve istisna doğru tepkiyse int.Parse(text) kullanın. Convert.ToInt32(text) int.Parse gibi davranır, yalnızca null için 0 döndürür.
int.Parse ile Convert.ToInt32 arasındaki fark nedir?
String'ler için neredeyse aynıdırlar: ikisi de "abc" gibi metinde FormatException, aralık dışı sayılarda OverflowException fırlatır. Fark null'dadır: int.Parse(null) ArgumentNullException fırlatır, Convert.ToInt32(null) ise 0 döndürür. Convert.ToInt32 başka tipleri de (double, bool, object) kabul eder ve bir double'ı kesmek yerine en yakın çift tamsayıya yuvarlar.
"Input string was not in a correct format" ne demek?
Metin beklenen biçimde bir sayı olmadığında int.Parse, double.Parse ya da Convert.ToInt32 tarafından fırlatılan bir FormatException'ın mesajıdır (.NET 8 ve sonrasında metni tırnak içinde vererek "The input string 'abc' was not in a correct format" der): harfler, boş bir string, bir int okunurken ondalık nokta ya da binlik ayırıcı. Hatalı girdiyi istisnasız ele almak için TryParse'a geçin ve sayının hangi kültürde yazıldığını kontrol edin.
C#'ta bir double int'e nasıl cast edilir?
Açık bir cast yazın: int n = (int)price;. Cast sıfıra doğru keser, yani (int)9.99 9, (int)-9.99 ise -9 olur. Yuvarlamak için (int)Math.Round(price) kullanın ve Math.Round'un varsayılan olarak yarımları en yakın çift sayıya yuvarladığını unutmayın; okulda öğretilen yuvarlama için MidpointRounding.AwayFromZero verin.
C#'ta as ile cast arasındaki fark nedir?
(Dog)animal cast'i, nesne bir Dog değilse InvalidCastException fırlatır. animal as Dog ise bunun yerine null döndürür, bu yüzden ardından bir null kontrolü gelmelidir ve yalnızca referans ve nullable tiplerle çalışır. Modern alternatif is desenidir: if (animal is Dog dog) { ... } tek adımda hem test eder hem dönüştürür.