[C#] InvariantCulture와 서수 문자열 비교의 차이점

c #에서 두 문자열이 동일한 지 비교할 때 InvariantCulture와 서수 비교의 차이점은 무엇입니까?



답변

불변의 문화

“표준”문자 순서 세트 (a, b, c, … 등)를 사용합니다. 이것은 ( ‘A-과 급성’전에 할 수있다 다른 순서의 문자를 정렬 할 수 있습니다 일부 특정 로케일, 대조적이다 또는 ‘A’는 지역에 따라, 등등 후).

서수

반면에 문자를 나타내는 원시 바이트 값을 순전히 살펴 봅니다.


http://msdn.microsoft.com/en-us/library/e6883c06.aspx 에는 다양한 StringComparison 값의 결과를 보여주는 훌륭한 샘플이 있습니다. 끝까지, 그것은 보여줍니다 (발췌) :

StringComparison.InvariantCulture:
LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131)
LATIN SMALL LETTER I (U+0069) is less than LATIN CAPITAL LETTER I (U+0049)
LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049)

StringComparison.Ordinal:
LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131)
LATIN SMALL LETTER I (U+0069) is greater than LATIN CAPITAL LETTER I (U+0049)
LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049)

InvariantCulture 수율 (U + 0069, U + 0049, U + 00131), 서수 수율 (U + 0049, U + 0069, U + 00131)이있는 곳을 확인할 수 있습니다.


답변

예를 들어, 캐릭터 확장이라는 것이 있습니다.

var s1 = "Strasse";
var s2 = "Straße";

s1.Equals(s2, StringComparison.Ordinal);           //false
s1.Equals(s2, StringComparison.InvariantCulture);  //true

함께 InvariantCulture친위대 문자 SS로 확대됩니다.


답변

가리키며 은 .NET Framework의 문자열을 사용하기위한 모범 사례 :

  • 문화권에 구애받지 않는 문자열 일치의 안전한 기본값으로 StringComparison.Ordinal또는 StringComparison.OrdinalIgnoreCase비교에 사용하십시오 .
  • 더 나은 성능을 위해 StringComparison.Ordinal또는 StringComparison.OrdinalIgnoreCase더 나은 성능을 위해 비교를 사용하십시오 .
  • 비교가 언어 적으로 관련이없는 경우 (예 : 상징적)를 기준으로 문자열 조작 대신 비 언어 StringComparison.Ordinal또는 StringComparison.OrdinalIgnoreCase값을 사용하십시오 CultureInfo.InvariantCulture.

그리고 마지막으로:

  • StringComparison.InvariantCulture대부분의 경우를 기준으로 문자열 연산을 사용하지 마십시오 . 몇 가지 예외 중 하나는 언어 적으로 의미가 있지만 문화적으로 불가지론적인 데이터를 유지하는 경우입니다.

답변

또 다른 편리한 차이점은 (영어에서 악센트가 드문 경우) InvariantCulture 비교는 전체 문자열을 대소 문자를 구분하지 않고 먼저 비교 한 다음 필요에 따라 (필요한 경우) 구별 문자 만 비교 한 후 대소 문자를 구분한다는 것입니다. (대소 문자를 구분하지 않는 대소 문자 구분 비교도 가능합니다.) 대소 문자를 구분하지 않습니다 .악센트 문자는 동일한 문자의 또 다른 풍미로 간주되며 문자열은 먼저 악센트를 무시한 다음 일반 문자가 모두 일치하는 경우 해당 문자를 고려합니다 (대소 문자를 구분하지 않는 비교에서 궁극적으로 무시되지 않는 경우를 제외하고는 대소 문자가 다름). 이 단어들은 첫 번째 억양 차이에서 완전히 분리되지 않고 서로 가까이있는 다른 단어의 억양 버전을 그룹화합니다. 이것은 사전에서 일반적으로 찾을 수있는 정렬 순서이며, 대문자로 된 단어는 소문자와 바로 옆에 나타나고 악센트 부호 문자는 해당하는 액센트가없는 문자 근처에 있습니다.

서수 비교는 숫자 값을 엄격하게 비교하여 첫 번째 차이에서 멈 춥니 다. 이렇게하면 대문자와 소문자가 완전히 분리되어 (대소 문자와 악센트 문자가 구분됨) 대문자로 된 단어는 소문자와 거의 일치하지 않습니다.

InvariantCulture는 또한 대문자가 소문자보다 큰 것으로 간주하는 반면, Ordinal은 대문자가 소문자보다 작은 것으로 간주합니다 (컴퓨터는 소문자를 사용하기 전 예전의 ASCII 보류, 대문자가 먼저 할당되어 소문자보다 낮은 값을 가짐) 나중에 추가).

예를 들어, 서수 : "0" < "9" < "A" < "Ab" < "Z" < "a" < "aB" < "ab" < "z" < "Á" < "Áb" < "á" < "áb"

그리고 InvariantCulture에 의해 : "0" < "9" < "a" < "A" < "á" < "Á" < "ab" < "aB" < "Ab" < "áb" < "Áb" < "z" < "Z"


답변

문제는 평등 에 관한 것이지만, 빠른 시각적 참조를 위해 여기서 일부 특질을 보여주는 몇 가지 문화를 사용하여 일부 문자열의 순서를 정렬 했습니다.

Ordinal          0 9 A Ab a aB aa ab ss Ä Äb ß ä äb      
IgnoreCase       0 9 a A aa ab Ab aB ss ä Ä äb Äb ß      
--------------------------------------------------------------------
InvariantCulture 0 9 a A  ä Ä aa ab aB Ab äb Äb ss ß     
IgnoreCase       0 9 A a  Ä ä aa Ab aB ab Äb äb ß ss     
--------------------------------------------------------------------
da-DK            0 9 a A  ab aB Ab ss ß ä Ä äb Äb aa     
IgnoreCase       0 9 A a  Ab aB ab ß ss Ä ä Äb äb aa     
--------------------------------------------------------------------
de-DE            0 9 a A  ä Ä aa ab aB Ab äb Äb ß ss     
IgnoreCase       0 9 A a  Ä ä aa Ab aB ab Äb äb ss ß     
--------------------------------------------------------------------
en-US            0 9 a A  ä Ä aa ab aB Ab äb Äb ß ss     
IgnoreCase       0 9 A a  Ä ä aa Ab aB ab Äb äb ss ß     
--------------------------------------------------------------------
ja-JP            0 9 a A  ä Ä aa ab aB Ab äb Äb ß ss     
IgnoreCase       0 9 A a  Ä ä aa Ab aB ab Äb äb ss ß     

관찰 :

  • de-DE, ja-JP그리고 en-US정렬 같은 방법으로
  • Invariant단지 종류 ssß다르게 위의 세 가지 문화
  • da-DK 상당히 다르게 정렬
  • IgnoreCase모든 샘플링 문화에 대한 플래그 사항

위의 테이블을 생성하는 데 사용되는 코드 :

var l = new List<string>
    { "0", "9", "A", "Ab", "a", "aB", "aa", "ab", "ss", "ß",
      "Ä", "Äb", "ä", "äb", "あ", "ぁ", "ア", "ァ", "A", "亜" };

foreach (var comparer in new[]
{
    StringComparer.Ordinal,
    StringComparer.OrdinalIgnoreCase,
    StringComparer.InvariantCulture,
    StringComparer.InvariantCultureIgnoreCase,
    StringComparer.Create(new CultureInfo("da-DK"), false),
    StringComparer.Create(new CultureInfo("da-DK"), true),
    StringComparer.Create(new CultureInfo("de-DE"), false),
    StringComparer.Create(new CultureInfo("de-DE"), true),
    StringComparer.Create(new CultureInfo("en-US"), false),
    StringComparer.Create(new CultureInfo("en-US"), true),
    StringComparer.Create(new CultureInfo("ja-JP"), false),
    StringComparer.Create(new CultureInfo("ja-JP"), true),
})
{
    l.Sort(comparer);
    Console.WriteLine(string.Join(" ", l));
}


답변

불변은 언어 적으로 적절한 유형의 비교입니다.
서수는 이진 유형의 비교입니다. (빠르게)
를 참조하십시오 http://www.siao2.com/2004/12/29/344136.aspx를


답변

다음은 InvariantCultureIgnoreCase와 OrdinalIgnoreCase를 사용한 문자열 동등 비교가 동일한 결과를 제공하지 않는 예입니다.

string str = "\xC4"; //A with umlaut, Ä
string A = str.Normalize(NormalizationForm.FormC);
//Length is 1, this will contain the single A with umlaut character (Ä)
string B = str.Normalize(NormalizationForm.FormD);
//Length is 2, this will contain an uppercase A followed by an umlaut combining character
bool equals1 = A.Equals(B, StringComparison.OrdinalIgnoreCase);
bool equals2 = A.Equals(B, StringComparison.InvariantCultureIgnoreCase);

이를 실행하면 equals1은 false가되고 equals2는 true가됩니다.