2012-12-19 4 views
15

http://msdn.microsoft.com/en-us/library/1x308yk8.aspxDlaczego każdy statyczny ciąg "Is ..." ma przeciążenie ciągu znaków, np. IsWhiteSpace (ciąg, Int32)?

To pozwala mi na to:

var str = "string "; 
Char.IsWhiteSpace(str, 6); 

zamiast:

Char.IsWhiteSpace(str[6]); 

Wydaje się niezwykłe, więc spojrzałem na refleksji:

[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 
public static bool IsWhiteSpace(char c) 
{ 
    if (char.IsLatin1(c)) 
    { 
     return char.IsWhiteSpaceLatin1(c); 
    } 
    return CharUnicodeInfo.IsWhiteSpace(c); 
} 

[SecuritySafeCritical] 
public static bool IsWhiteSpace(string s, int index) 
{ 
    if (s == null) 
    { 
     throw new ArgumentNullException("s"); 
    } 
    if (index >= s.Length) 
    { 
     throw new ArgumentOutOfRangeException("index"); 
    } 
    if (char.IsLatin1(s[index])) 
    { 
     return char.IsWhiteSpaceLatin1(s[index]); 
    } 
    return CharUnicodeInfo.IsWhiteSpace(s, index); 
} 

trzy rzeczy uderzyło mnie:

  1. Dlaczego nie warto sprawdzać limitu tylko przy górnej granicy? Rzucanie ArgumentOutOfRangeException, podczas gdy indeks poniżej 0 dawałby standardowy łańcuch znaków, o którym czytałem ogólne oblewanie, ale nadal nie jest jasne, co tu robi i czy jest połączony z kontrolą górnego ograniczenia.
  2. TargetedPatchingOptOutAttribute nie występuje na innych metodach Is...(char). Przykład IsLetter, IsNumber itp

Odpowiedz

18

Ponieważ nie każda postać pasuje do C# char. Na przykład: "" zajmuje 2 C# chars, a nie można uzyskać żadnych informacji o tej postaci z tylko przeciążeniem char. Z wartością String i indeksem metody mogą sprawdzić, czy znak o indeksie i jest wysokim zastępcą char, a następnie odczytać wartość Niskie dane zastępcze char przy następnym indeksie, add them up according to the algorithm i pobrać informacje o kodzie U+20000.

W ten sposób UTF-16 może kodować 1 milion różnych punktów kodowych, jest to kodowanie o zmiennej szerokości. Zajmuje 2-4 bajty, aby zakodować znak lub 1-2 znaki C#.

4

Dlaczego nie warto sprawdzać limitu tylko przy górnej granicy?

Nie dotyczy. Wykonuje on porównanie z unsigned, więc każda liczba ujemna będzie porównywać większy niż długość i spowoduje wygenerowanie odpowiedniego wyjątku. Zdarza się, że nie zostanie dokładnie zeskompilowany.

+0

Ah, niezły chwyt, dzięki. Ludzie powinni się tym przejmować, to się sprawdza! 'IL_0015: blt.un.s IL_0022' – weston

Powiązane problemy