, 두 개의 문자열을 lowercasing하고 비교는 무시의 경우를 비교하고 동일하지 않습니다. 이것에 대한 많은 이유가 있습니다. 예를 들어, 유니 코드 표준은 발음 구별이있는 텍스트를 여러 가지 방법으로 인코딩 할 수 있습니다. 일부 문자는 기본 문자와 분음 부호를 단일 코드 포인트에 포함합니다. 이 문자들은 기본 문자와 결합 발음 구별 문자로 표시 될 수 있습니다. 이 두 표현은 모든 목적에 동일하며 .NET Framework의 문화권 인식 문자열 비교는 CurrentCulture 또는 InvariantCulture (IgnoreCase 포함 또는 제외)를 사용하여 동일하게 식별합니다. 다른 한편으로 서수 비교는 그것들을 불평등 한 것으로 잘못 간주 할 것이다.
불행히도 switch
은 서수 비교를하지 않습니다. 정렬 된 코드는 엄격하게 정의 된 코드로 ASCII 파일을 구문 분석하는 것과 같은 특정 종류의 응용 프로그램에서는 좋지만 대부분의 다른 용도에서는 서수 문자열 비교가 잘못되었습니다.
올바른 행동을 취하기 위해 내가 한 일은 저의 switch 문을 조롱하는 것입니다. 이를 수행 할 수있는 방법이 많이 있습니다. 한 가지 방법은 List<T>
쌍의 사례 문자열과 대리자를 만드는 것입니다. 목록은 적절한 문자열 비교를 사용하여 검색 할 수 있습니다. 일치가 발견되면 연관된 델리게이트가 호출 될 수 있습니다.
또 다른 옵션은 if
문장의 명백한 체인을 수행하는 것입니다. 이것은 구조가 매우 규칙적이기 때문에 일반적으로 들리는 것처럼 나쁘지는 않습니다.
대단한 점은 문자열과 비교할 때 자신의 스위치 기능을 조롱하는 데 성능상의 불이익이 없다는 것입니다. 시스템은 정수로 할 수있는 방식으로 O (1) 점프 테이블을 만들지 않으므로 어쨌든 한 번에 하나씩 각 문자열을 비교하게 될 것입니다.
비교할 사례가 많고 성능이 문제가되는 경우 위에서 설명한 List<T>
옵션을 정렬 된 사전 또는 해시 테이블로 바꿀 수 있습니다. 그러면 성능이 switch 문의 옵션과 잠재적으로 일치하거나 초과 할 수 있습니다.
물론
delegate void CustomSwitchDestination();
List<KeyValuePair<string, CustomSwitchDestination>> customSwitchList;
CustomSwitchDestination defaultSwitchDestination = new CustomSwitchDestination(NoMatchFound);
void CustomSwitch(string value)
{
foreach (var switchOption in customSwitchList)
if (switchOption.Key.Equals(value, StringComparison.InvariantCultureIgnoreCase))
{
switchOption.Value.Invoke();
return;
}
defaultSwitchDestination.Invoke();
}
, 당신은 아마도 아마도 몇 가지 표준 매개 변수와 CustomSwitchDestination 위임에 반환 유형을 추가 할 것 : 여기
는 대표 목록의 예입니다. 그리고 당신은 더 나은 이름을 만들고 싶어합니다!
differnt 매개 변수가 필요한 경우와 같이 각 사례의 동작이 이러한 방식으로 호출을 위임 할 수없는 경우 연결된 if
문장이 붙어 있습니다. 나는 이것을 몇 번 했어.
if (s.Equals("house", StringComparison.InvariantCultureIgnoreCase))
{
s = "window";
}
else if (s.Equals("business", StringComparison.InvariantCultureIgnoreCase))
{
s = "really big window";
}
else if (s.Equals("school", StringComparison.InvariantCultureIgnoreCase))
{
s = "broken window";
}
내가 틀린 것이 아니라면이 두 언어는 특정 문화권 (터키어 등)에서만 다르며이 경우 'ToUpperInvariant()'또는 'ToLowerInvariant()'를 사용할 수 없습니까? 또한, 그는 두 개의 알려지지 않은 문자열을 비교하지 않습니다. 그는 하나의 알려지지 않은 문자열과 알려진 문자열을 비교합니다. 따라서 적절한 대소 문자 표현을 하드 코딩하는 방법을 알고있는 한 스위치 블록이 잘 작동해야합니다. –
@Seth Petry-Johnson - 최적화가 가능할 수도 있지만 문자열 비교 옵션이 프레임 워크에 구워지는 이유는 올바른 확장 가능한 소프트웨어를 작성하는 데 언어학 전문가가되어야하는 것은 아닙니다. –
확인. 이것이 relivant 인 경우를 예로 들어 보겠습니다. "집"대신에 우리는 (영어!) 단어 "카페"를 가지고 있다고 가정합니다. 이 값은 "caf \ u00E9"또는 "cafe \ u0301"에 의해 동일하게 잘 표현 될 수 있습니다. 'ToLower()'또는 'ToLowerInvariant()'와 같은 서수 항등식 (switch 문에서와 같이)은 false를 반환합니다. 'Equals'와'StringComparison.InvariantCultureIgnoreCase'는 true를 리턴합니다. 두 시퀀스는 표시 될 때 동일하게 보이기 때문에'ToLower()'버전은 추적하기에 더러운 버그입니다. 터키인이 아니더라도 적절한 문자열 비교를하는 것이 항상 최선의 방법입니다. –