2012-01-16 12 views
7

Bir şey kaçırıp kaçırmadığımı bilmek isterim ... Standart İngiliz kültürü altında koşuyorum.Double.TryParse() NumberFormatInfo.NumberGroupSizes'i yoksayar?

Double result = 0; 
if (Double.TryParse("1,2,3", NumberStyles.Any, CultureInfo.CurrentCulture, out result)) 
{ 
    Console.WriteLine(result); 
} 

Beklenen çıktı hiçbir şey olmaz ... "1,2,3" çift olarak ayrıştırılmamalıdır. Ancak öyle. NET 2,0 MSDN documentation

AllowThousands göre sayısal dize grup ayırıcılar olabileceğini gösterir; Örneğin yüz binlerce kişiden ayrılıyor. Geçerli grubu ayırıcı karakter NumberFormatInfo arasında NumberGroupSeparator ve CurrencyGroupSeparator özellikleri ve NumberFormatInfo ait NumberGroupSizes ve CurrencyGroupSizes özellikleri ile belirlenir, her bir gruptaki basamak sayısı ile tespit edilir.

Sayıların sayısı NumberStyles.Any'de bulunabilir. Kültürüm için NumberGroupSizes 3'tür. Bu, Double.Parse'deki bir hata mı? olası görünmüyor ama neyi yanlış yaptığımı göremiyorum ....

+0

Bu olabilir test ederken ben geçerli bir sonuç aldık niye [cevabım] (http://stackoverflow.com/questions/1014535/float-parse-doesnt-work-the -way-i-aranıyor/1014559 # 1014559) benzer bir soru üzerine. – ChrisF

+0

Sadece merak, ama sonuç değeri nedir? – Aaron

+0

Sanırım Microsoft'a bir hata mı soruyorsunuz, ama seninle aynı davranışı alıyorum. Her zaman 'NumberStyles.Any^NumberStyles.AllowThousands' yapabilirsiniz, ancak üçlü yasal gruplarını bekliyoruz eğer çok fazla değil. – Jodrell

cevap

5

Sadece giriş dizesinin NumberFormatInfo.NumberGroupSeparator sıfır veya daha fazla örneğini içerebileceği anlamına gelir. Bu ayırıcı, herhangi bir boyuttaki sayı gruplarını ayırmak için kullanılabilir; sadece binlerce değil. NumberFormatInfo.NumberGroupSeparator ve NumberFormatInfo.NumberGroupSizes, ondalık sayıları dizeler olarak biçimlendirirken kullanılır. Reflektör kullanmak NumberGroupSeparator sadece karakterin bir ayırıcı olup olmadığını belirlemek için kullanılır ve eğer varsa atlanır. NumberGroupSizes hiç kullanılmıyor.

Dizeyi doğrulamak isterseniz, RegEx'i kullanarak veya bunu yapmak için bir yöntem yazabilirsiniz. İşte biri sadece birlikte kesmek:

string number = "102,000,000.80"; 
var parts = number.Split(','); 
for (int i = 0; i < parts.Length; i++) 
{ 
    var len = parts[i].Length; 
    if ((len != 3) && (i == parts.Length - 1) && (parts[i].IndexOf('.') != 3)) 
    { 
     Console.WriteLine("error"); 
    } 
    else 
    { 
     Console.WriteLine(parts[i]); 
    } 
} 

// Respecting Culture 
static Boolean CheckThousands(String value) 
{ 
    String[] parts = value.Split(new string[] { CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator }, StringSplitOptions.None); 
    foreach (String part in parts) 
    { 
     int length = part.Length; 
     if (CultureInfo.CurrentCulture.NumberFormat.NumberGroupSizes.Contains(length) == false) 
     { 
      return false; 
     } 
    } 

    return true; 
} 
+0

+1, 'NumberGroupSizes' ayrıştırmada yok sayılır (iç yöntem "Number.ParseNumber"). – user7116

+0

Reflektör ile kazmaya başladım, ama henüz bu kadar aşağıya inme vakti yoktu. Regex kullanmayı düşünüyorum, ama dikkatli olmalı ve kültürün farkında olduğundan emin olmalıyım. – Ian

+0

@Ian Regex ifadelerinizi, her kültür için NumberFormatInfo'da depolanan bilgilere dayanarak oluşturabilirsiniz. –

İlgili konular