StringComparison.OrdinalIgnoreCase 또는 StringComparison.InvariantCultureIgnoreCase는 일반적으로 가장 적합한 방법은 무엇입니까?


162

다음과 같은 코드가 있습니다.

If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
    DoSomething()
End If

나는 그 사건에 관심이 없다. 내가 사용 하는가 OrdinalIgnoreCase, InvariantCultureIgnoreCase또는 CurrentCultureIgnoreCase?


2
이 스레드에 실제로 유용한 지 확인하십시오. ordianlignorecase를 사용하여 비교할 것을 제안합니다. blogs.msdn.com/b/noahc/archive/2007/06/29/…
UmaMaheswaran


전반적으로, 그것은 당신이 비교하는 종류에 달려 있습니다. 특히 문화에 의존하는 사용자 입력 또는 내부 자료 인 경우. PC의 문화가 내부 코드 문자열 비교를 망칠 필요는 없습니다.
Nyerguds

답변:


180

최신 .Net Docs에는 현재 상황에 가장 적합한 것을 결정하는 데 도움이되는 표가 있습니다.

MSDN의 " Microsoft .NET 2.0에서 문자열 사용에 대한 새로운 권장 사항 "에서

요약 : 이전 InvariantCulture에 문자열 비교, 케이싱 및 정렬 에 사용했던 코드 소유자 String는 Microsoft .NET 2.0에서 새로운 오버로드 집합을 사용해야합니다 . 특히 문화에 구애받지 않고 언어 적으로 관련이 없도록 설계된 데이터 는 새 열거 형 StringComparison.Ordinal또는 StringComparison.OrdinalIgnoreCase멤버를 사용하여 오버로드를 지정해야합니다 StringComparison. 이것들 strcmp은 본질적으로 상징적 인 문자열의 언어 적 해석으로 인한 버그를 피할뿐만 아니라 더 나은 성능을 제공한다는 점 과 비슷한 바이트 별 비교를 강제합니다 .


126
차이점이있는 예제를 제공하려면 두 문자열 "Straße"및을 고려하십시오 "STRASSE". 사용하는 경우 수익을 , 반면 그들이 동일한있어 말한다. OrdinalIgnoreCaseEqualsfalseInvariantCultureIgnoreCase
Jeppe Stig Nielsen


64

그것은 모두 달려있다

유니 코드 문자열을 비교하는 것은 어렵습니다.

텍스트 처리 소프트웨어에서 유니 코드 문자열 검색 및 비교를 구현하려면 동등한 코드 포인트가 있어야합니다. 이 기능이 없으면 특정 코드 포인트 시퀀스를 검색하는 사용자는 다르지만 정식으로 코드 포인트가 다른 시각적으로 구분할 수없는 글리프를 찾을 수 없습니다.

참조 : http://en.wikipedia.org/wiki/Unicode_equivalence


대소 문자를 구분하지 않는 방식으로 두 개의 유니 코드 문자열을 비교하려고하고 어디서나 작동 하려면 불가능한 문제가 있습니다.

고전적인 예는 터키어 i 이며 대문자로 표시하면 İ가됩니다 (점에 유의).

기본적으로 .Net 프레임 워크는 문자열 관련 함수에 CurrentCulture.Equals사용하지만 서수 (바이트 단위) 비교를 사용하는 것을 제외하고는 매우 중요한 예외가 있습니다.

이것은 의도적으로 컴퓨터의 문화에 따라 다르게 작동하는 다양한 문자열 기능으로 이어집니다.


그럼에도 불구하고 때때로 우리는 대소 문자를 구분하지 않는 "일반적인 목적"을 원합니다.

예를 들어, 응용 프로그램이 설치된 컴퓨터에 관계없이 문자열 비교가 동일한 방식으로 작동하기를 원할 수 있습니다.

이를 위해 3 가지 옵션이 있습니다.

  1. 문화권을 명시 적으로 설정하고 유니 코드 동등성 규칙을 사용하여 대소 문자를 구분하지 않는 비교를 수행하십시오.
  2. 문화권을 고정 문화권으로 설정하고 유니 코드 동등성 규칙을 사용하여 대소 문자를 구분하지 않는 비교를 수행하십시오.
  3. InvariantCulture를 사용하여 문자열을 대문자로 한 바이트 단위 비교를 수행하는 OrdinalIgnoreCase 를 사용하십시오 .

유니 코드 동등성 규칙은 복잡하므로 방법 1) 또는 2)를 사용하는 것보다 비용이 많이 듭니다 OrdinalIgnoreCase. OrdinalIgnoreCase특별한 유니 코드 정규화를 수행하지 않는다는 사실 은 컴퓨터 화면에서 동일한 방식으로 렌더링되는 일부 문자열이 동일하게 간주 되지 않음을 의미합니다. 예를 들면 다음 "\u0061\u030a"과 같습니다 "\u00e5". 그러나 서수 비교에서는 다른 것으로 간주됩니다.

당신이 선택하는 것은 당신이 만들고있는 어플리케이션에 달려 있습니다.

  • 터키 사용자 만 사용하는 LOB (기간 업무) 앱을 작성하는 경우 방법 1을 사용해야합니다.
  • 예를 들어 db의 열 이름과 같이 간단한 "가짜"대소 문자 구분 비교가 필요한 경우 보통 영어 3 방법을 사용합니다.

Microsoft는 명확한 지침과 함께 권장 사항을 제시 합니다. 그러나 이러한 문제에 접근하기 전에 유니 코드 동등성의 개념을 이해하는 것이 정말로 중요합니다.

또한, OrdinalIgnoreCase는 매우 특수한 종류 의 짐승 이라는 점을 명심하십시오. 이는 서사적 측면에서 혼합 된 일부와 약간의 서수 비교를 선택하고 선택하는 것입니다. 혼란 스러울 수 있습니다.


터키 사용자 만 사용하는 터키어 앱을 작성하고 있는데 "ayakkabı"와 "ayakkabi"가 같으면 어떻게해야합니까? 사람들이 휴대 전화로 입력 할 때 대부분은 기본적으로 영어 키보드를 사용하며 "ı"또는 "i"를 입력해도 상관 없습니다.
Volkan Sen

4

나는 그것이 당신의 상황에 달려 있다고 생각합니다. 서수 비교는 실제로 문자의 숫자 유니 코드 값을보고 있기 때문에 알파벳순으로 정렬 할 때 최선의 선택이 아닙니다. 그러나 문자열 비교의 경우 서수는 약간 빠릅니다.


1

당신이 아니라면 난 도망 invariantculture 부끄러워 것하지만 그것은 당신이 원하는에 따라 매우 당신이 다른 언어에 대한 코드를 지역화하고 싶지는 않을 것이다. 대신 CurrentCulture를 사용하십시오.

또한, OrdinalIgnoreCase는 원하는 숫자 일 수도 있고 아닐 수도있는 숫자를 존중해야합니다.


1
혼합 언어 환경에서 VB6 코드를 작성한 적이 있습니까? 양식 리소스에 저장된 숫자는 현재 로캘의 형식을 사용하기 때문에 프랑스어 로캘이있는 PC에서는 컴파일되지만 영어 로캘이있는 PC에서는 컴파일되지 않는 코드를 만들 수 있습니다. 나는 당신이 반대의 접근법을 취해야한다고 주장한다 : 현재 문화를 사용할 때 매우 조심하라. 데이터가 문화권간에 이동할 때 시스템이 여전히 작동하는지 항상 생각하십시오. 시간대와 같은 것.
Wim Coenen

나는 "의존"답변에 동의합니다. "존중 번호"비트를 따르지 않습니까?
Sam Saffron

-1

매우 간단한 대답은 터키어를 사용하지 않는 한 InvariantCulture를 사용할 필요가 없다는 것입니다.

다음 링크를 참조하십시오.

C #에서 ToUpper ()와 ToUpperInvariant ()의 차이점은 무엇입니까?


5
이 답변은 간단 할 수도 있지만 매우 잘못되었습니다. 터키어 "I"는 단지 예일 뿐이며, 더 많은 함정이있을 수 있습니다.
하드 슈나이더

어떤 함정이 더 있습니까? 터키 문제 사례 만 알고 있습니다.
HelloWorld

예, 터키어 외에도 아 제리가 있습니다. 하지만 그게 다야.
Jim Balter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.