2011-01-13 19 views
7

Kısa soru:C# Decimal.Parse davranış

Neden .NET (C#) bir ondalık ayrıştırmak için bu '.....' geçerli: nedeni nedir

decimal res = decimal.Parse("8......15"); // returns 815 
decimal res = decimal.Parse("8...15");  // returns 815 
decimal res = decimal.Parse("8..15");  // returns 815 

bu?

+0

ben .NET4.0 bunu kontrol ettik. Biçim istisnasını artırır – HuBeZa

+0

Hangi kültürü kullanıyorsunuz? Bu dizeler şu andaki kültürümü veya değişmez kültürü kullanarak ayrıştırılamaz. – LukeH

+0

Sanırım programcı tembelliği. Bin ayırıcıyı gevşek bir şekilde kullanan bir yer görmedim. – HuBeZa

cevap

18

Bu benim için başarısız. "." Nin bulunduğu bir kültürde şansın var mı? binlik ayırıcı ve "," ondalık noktası nedir? Decimal.Parse (ve benzer aramalar), iş parçacığının geçerli kültürünü varsayılan olarak kullanır. Bu iyi bir şey olsun ya da olmasın

decimal.Parse çağrısında CultureInfo.InvariantCulture belirtmeyi deneyin gerçek davranışı :) için tartışılabilir, ama ilgisiz:

decimal res = decimal.Parse("8......15", CultureInfo.InvariantCulture); 

Sana beklendiği gibi olduğunu davranacaktır inanıyoruz.

+0

Sanırım kafanın üzerindeki çiviye çarpmışsın. Örneğin 'de-DE' kültürünü kullanırsanız doğru şekilde ayrıştırılır. – LukeH

+0

'es-ES' için. Ne garip bir kültür – HuBeZa

+0

Gerçekten de. CurrentCulture "nl-BE", NumberDecimalSeparator = "," ve NumberGroupSeparator = "şeklindedir. Teşekkürler! Fakat böyle bir gösterime izin vermeleri oldukça garip. – juFo

1

Nedenini bilmiyorum ama nasıl çalıştığını biliyorum (ondalık ayrıştırıcı kod parçası aşağıya bakın). Sanırım son noktayı işaretlemeli ve tüm noktaları atla.

while (true) 
{ 
    if (((ch >= '0') && (ch <= '9')) || (((options & NumberStyles.AllowHexSpecifier) != NumberStyles.None) && (((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'F'))))) 
    { 
     //Here goes some code... 
    } 
    else if ((((options & NumberStyles.AllowDecimalPoint) != NumberStyles.None) && ((num & 0x10) == 0)) 
    && (((chPtr2 = MatchChars(p, currencyDecimalSeparator)) != null) || ((flag && ((num & 0x20) == 0)) 
    && ((chPtr2 = MatchChars(p, numberDecimalSeparator)) != null)))) 
    { 
     num |= 0x10; 
     p = chPtr2 - 1; 
    } 
} 

Tüm kodu araştırmak için Reflektör aracını kullanın.

+0

İlginç! HexSpecifier hakkında parça kodunu görmek güzel. – juFo

2

Bunun sebebi, ayrıştırıcının grup ayırıcılarını gerçekten umursamadığı için düşünürdüm - bir dizeyi bir ondalığa dönüştürme işlemiyle ilgisizler.

Onlara binlerce ayırıcı diyoruz, ama gerçekten değiller. Onlar grup ayırıcılarıdır - her 3 basamağı, her 10 haneyi, her 1 basamağı bölebilirsin, o zaman neden her 0 rakamı olmasın?

İlginçtir, kod .NET 4 için değişti - bu benim için Reflektör alakalı çıkışı:

else 
{ 
    if (((currencySymbol == null) || 
     ((chPtr2 = MatchChars(p, currencySymbol)) == null)) && 
     ((ansiCurrencySymbol == null) || 
     ((chPtr2 = MatchChars(p, ansiCurrencySymbol)) == null))) 
    { 
     break; 
    } 
    num |= 0x20; 
    currencySymbol = null; 
    ansiCurrencySymbol = null; 
    p = chPtr2 - 1; 
}