it-swarm-ko.tech

Switch 문의 여러 사례

case value:를 반복적으로 언급하지 않고 여러 사례 문을 통과 할 수있는 방법이 있습니까?

나는이 작품을 알고 :

switch (value)
{
   case 1:
   case 2:
   case 3:
      //do some stuff
      break;
   case 4:
   case 5:
   case 6:
      //do some different stuff
      break;
   default:
       //default stuff
      break;
}

하지만 이런 식으로하고 싶습니다 :

switch (value)
{
   case 1,2,3:
      //Do Something
      break;
   case 4,5,6:
      //Do Something
      break;
   default:
      //Do the Default
      break;
}

이 문법은 다른 언어로 생각하고 있습니까, 아니면 뭔가 빠져 있습니까?

517
theo

언급 한 두 번째 방법에는 C++이나 C #에서 구문이 없습니다.

첫 번째 방법에는 아무런 문제가 없습니다. 그러나 매우 큰 범위가있는 경우 일련의 if 문을 사용하십시오.

282
Brian R. Bondy

나는 이것이 이미 응답 된 것 같아요. 그러나 다음과 같이 구문 적으로 더 나은 방법으로 두 옵션을 혼합 할 수 있다고 생각합니다.

switch (value)
{
case 1: case 2: case 3:          
    // Do Something
    break;
case 4: case 5: case 6: 
    // Do Something
    break;
default:
    // Do Something
    break;
}
640

이 구문은 Visual Basic Select ... Case 문 :

Dim number As Integer = 8
Select Case number
    Case 1 To 5
        Debug.WriteLine("Between 1 and 5, inclusive")
        ' The following is the only Case clause that evaluates to True.
    Case 6, 7, 8
        Debug.WriteLine("Between 6 and 8, inclusive")
    Case Is < 1
        Debug.WriteLine("Equal to 9 or 10")
    Case Else
        Debug.WriteLine("Not between 1 and 10, inclusive")
End Select

C #에서는이 구문을 사용할 수 없습니다. 대신 첫 번째 예제의 구문을 사용해야합니다.

65
Neal

원래 질문에 대한 답변이 조금 늦었지만 새로운 버전 (C # 7 - Visual Studio 2017/.NET Framework 4.6.2에서 기본적으로 사용 가능)을 사용하는 사람이이 대답을 게시 할 예정입니다. 도움이 되십시오.

C # 7에서는 switch 문 을 사용하여 범위 기반 전환이 가능하며 OP 문제를 해결하는 데 도움이됩니다.

예:

int i = 5;

switch (i)
{
    case int n when (n >= 7):
        Console.WriteLine($"I am 7 or above: {n}");
        break;

    case int n when (n >= 4 && n <= 6 ):
        Console.WriteLine($"I am between 4 and 6: {n}");
        break;

    case int n when (n <= 3):
        Console.WriteLine($"I am 3 or less: {n}");
        break;
}

// Output: I am between 4 and 6: 5

노트:

  • 괄호 ()when 조건에는 필요하지 않지만이 예제에서는 비교를 강조 표시하는 데 사용됩니다.
  • var 대신 int을 사용할 수도 있습니다. 예 : case var n when n >= 7:.
47
Steve Gomez

다음과 같은 개행을 생략 할 수 있습니다.

case 1: case 2: case 3:
   break;

그러나 나는 그 나쁜 스타일을 고려한다.

31
Allan Wind

.NET Framework 3.5에 범위가 있습니다.

Enumerable.Range from MSDN

누군가가 SWITCH 문에서 "=="연산자를 사용한다고했기 때문에 "contains"와 IF 문과 함께 사용할 수 있습니다.

예를 들면 다음과 같습니다.

int c = 2;
if(Enumerable.Range(0,10).Contains(c))
    DoThing();
else if(Enumerable.Range(11,20).Contains(c))
    DoAnotherThing();

하지만 우리는 더 많은 재미를 가질 수 있다고 생각합니다. 반환 값이 필요 없으며 매개 변수를 취하지 않기 때문에 작업을 쉽게 사용할 수 있습니다!

public static void MySwitchWithEnumerable(int switchcase, int startNumber, int endNumber, Action action)
{
    if(Enumerable.Range(startNumber, endNumber).Contains(switchcase))
        action();
}

이 새로운 방법을 사용한 예는 다음과 같습니다.

MySwitchWithEnumerable(c, 0, 10, DoThing);
MySwitchWithEnumerable(c, 10, 20, DoAnotherThing);

값이 아닌 액션을 전달하기 때문에 괄호를 생략해야합니다. 매우 중요합니다. 인수가있는 함수가 필요한 경우 Action 유형을 Action<ParameterType>로 변경하면됩니다. 반환 값이 필요하면 Func<ParameterType, ReturnType>를 사용하십시오.

C # 3.0에서는 case 매개 변수가 동일하다는 사실을 캡슐화하는 쉬운 부분 응용 프로그램 이 없지만 약간의 도우미 메서드 (조금 자세하게, tho)를 만듭니다.

public static void MySwitchWithEnumerable(int startNumber, int endNumber, Action action){ 
    MySwitchWithEnumerable(3, startNumber, endNumber, action); 
}

여기에 새로운 기능 임포트 된 명령문이 이전의 명령형보다 IMHO가 더 강력하고 우아하다는 예가 나와 있습니다.

18
Luca Molteni

@ Jennifer Owens : 당신은 절대적으로 옳다. 아래의 코드는 작동하지 않을 것이다 :

case 1 | 3 | 5:
//not working do something

이렇게하는 유일한 방법은 다음과 같습니다.

case 1: case 2: case 3:
// do something
break;

찾고있는 코드는 비주얼 베이직에서 작동하여 범위를 넣을 수 있습니다 ... 전환 옵션이 없거나 편리한 블록이 있다면 매우 극단적 인 시점에서 .dll을 시각 기본 및 가져 오기로 다시 만들 것을 제안합니다. 귀하의 C # 프로젝트.

참고 : 시각적 기본에서 스위치를 동일하게하는 것이 좋습니다.

8
none

또 다른 옵션은 루틴을 사용하는 것입니다. 케이스 1-3 모두 동일한 로직을 실행 한 다음 해당 로직을 루틴으로 랩핑하고 각 케이스에 대해 호출하십시오. 나는 이것이 실제로 케이스 진술을 제거하지 않는다는 것을 알고있다, 그러나 좋은 작풍을 실행하고 유지를 최소한에 지킨다 .....

[편집] 원래 질문과 일치하는 대체 구현 추가 ... [/ 편집]

switch (x)
{
   case 1:
      DoSomething();
      break;
   case 2:
      DoSomething();
      break;
   case 3:
      DoSomething();
      break;
   ...
}

private void DoSomething()
{
   ...
}

Alt

switch (x)
{
   case 1:
   case 2:
   case 3:
      DoSomething();
      break;
   ...
}

private void DoSomething()
{
   ...
}
7
Dr8k

gcc는 연속 범위를 지원하기 위해 C 언어에 대한 확장을 구현합니다.

switch (value)
{
   case 1...3:
      //Do Something
      break;
   case 4...6:
      //Do Something
      break;
   default:
      //Do the Default
      break;
}

편집하다: 그냥 질문에 C # 태그를 발견, 그래서 아마도 gcc는 도움이되지 않습니다.

5
DGentry

다음은 완벽한 C # 7 솔루션입니다.

switch (value)
{
   case var s when new[] { 1,2,3 }.Contains(s):
      //Do Something
      break;
   case var s when new[] { 4,5,6 }.Contains(s):
      //Do Something
      break;
   default:
      //Do the Default
      break;
}

문자열과도 호환됩니다 ...

switch (mystring)
{
   case var s when new[] { "Alpha","Beta","Gamma" }.Contains(s):
      //Do Something
      break;
...
}
5
Carter Medlin

C #에서 switch 에 대해 잘 알려지지 않은 부분은 operator = 에 의존한다는 것입니다. 그리고 다음과 같은 것을 가질 수 있기 때문에 오버 라이딩 될 수 있습니다 :


string s = foo();

switch (s) {
  case "abc": /*...*/ break;
  case "def": /*...*/ break;
}
5

사실 나는 GOTO 명령도 좋아하지 않지만 공식 MS 자료에 있습니다. 여기서 허용되는 모든 구문이 있습니다.

스위치 섹션의 명령문 목록의 끝점에 도달 할 수 있으면 컴파일 타임 오류가 발생합니다. 이를 "폴 스루 스루 없음"규칙이라고합니다. 예제

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
default:
   CaseOthers();
   break;
}

도달 할 수있는 끝점이있는 스위치 섹션이 없기 때문에 유효합니다. C 및 C++과는 달리, 스위치 섹션 실행은 다음 스위치 섹션으로 "넘어갈"수 없으며 예제

switch (i) {
case 0:
   CaseZero();
case 1:
   CaseZeroOrOne();
default:
   CaseAny();
}

컴파일시 오류가 발생합니다. 스위치 섹션의 실행이 다른 스위치 섹션의 실행에 이어질 때 명시적인 goto case 또는 goto default 문이 사용되어야합니다.

switch (i) {
case 0:
   CaseZero();
   goto case 1;
case 1:
   CaseZeroOrOne();
   goto default;
default:
   CaseAny();
   break;
}

스위치 섹션에는 여러 개의 레이블이 허용됩니다. 예제

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
case 2:
default:
   CaseTwo();
   break;
}

나는이 특별한 경우를 믿습니다. GOTO가 사용될 수 있습니다. 실제로는 넘어 질 수있는 유일한 방법입니다.

출처 : http://msdn.Microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx

3
Jiří Herník

엄청난 양의 일이 C #에서 사용 된 구문 중 하나를 더 좋아 보이게하거나 더 잘 작동하도록 만드는 방법을 찾은 것으로 보인다. 개인적으로 switch 문이 거의 쓸만한 가치가 없다는 것을 알았습니다. 나는 당신이 테스트하고있는 데이터와 당신이 원하는 최종 결과를 분석 할 것을 강력히 제안 할 것이다.

예를 들어 알려진 범위의 값을 신속하게 테스트하여 소수인지 확인하고자한다고 가정 해 보겠습니다. 코드에서 낭비되는 계산을 피하고 온라인에서 원하는 범위의 소수 목록을 찾을 수 있습니다. 방대한 switch 문을 사용하여 각 값을 알려진 소수와 비교할 수 있습니다.

또는 소수의 배열지도를 만들고 즉각적인 결과를 얻을 수 있습니다.

    bool[] Primes = new bool[] {
        false, false, true, true, false, true, false,    
        true, false, false, false, true, false, true,
        false,false,false,true,false,true,false};
    private void button1_Click(object sender, EventArgs e) {
        int Value = Convert.ToInt32(textBox1.Text);
        if ((Value >= 0) && (Value < Primes.Length)) {
            bool IsPrime = Primes[Value];
            textBox2.Text = IsPrime.ToString();
        }
    }

어쩌면 문자열의 문자가 16 진수인지 확인할 수 있습니다. 당신은 엉터리이고 다소 큰 switch 문을 사용할 수 있습니다.

또는 정규식을 사용하여 char을 테스트하거나 IndexOf 함수를 사용하여 알려진 16 진수 문자열로 char을 검색 할 수 있습니다.

        private void textBox2_TextChanged(object sender, EventArgs e) {
        try {
            textBox1.Text = ("0123456789ABCDEFGabcdefg".IndexOf(textBox2.Text[0]) >= 0).ToString();
        } catch {
        }
    }

1부터 24까지의 값에 따라 3 가지 다른 액션 중 하나를하고 싶다고합시다. IF 문을 사용하는 것이 좋습니다. 그리고 그것이 너무 복잡 해지면 (숫자가 1에서 90까지의 값에 따라 5 가지 다른 액션과 같이 더 컸다면) enum을 사용하여 액션을 정의하고 열거 형의 배열 맵을 만듭니다. 그런 다음이 값을 사용하여 배열 맵에 색인을 작성하고 원하는 작업의 열거 형을 가져옵니다. 그런 다음 작은 수의 IF 문 또는 매우 간단한 switch 문을 사용하여 결과로 나오는 열거 형 값을 처리하십시오.

또한 범위 값을 액션으로 변환하는 배열 맵에 대한 좋은 점은 코드로 쉽게 변경할 수 있다는 것입니다. 하드 유선 코드를 사용하면 런타임에 동작을 쉽게 변경할 수 없지만 배열 맵을 사용하면 쉽게 수행 할 수 있습니다.

2
Darin

만약 당신이 문자열 (또는 다른 유형) 매우 큰 금액을 모두 동일한 일을하고, 나는 stringandContains 속성과 결합 문자열 목록의 사용을 recommand.

그래서 다음과 같은 큰 switch 문이 있다면 :

switch (stringValue)
{
    case "cat":
    case "dog":
    case "string3":
    ...
    case "+1000 more string": //Too many string to write a case for all!
        //Do something;
    case "a lonely case"
        //Do something else;
    .
    .
    .
}

다음과 같이 if 문으로 대체 할 수 있습니다.

//Define all the similar "case" string in a List
List<string> listString = new List<string>(){ "cat", "dog", "string3", "+1000 more string"};
//Use string.Contains to find what you are looking for
if (listString.Contains(stringValue))
{
    //Do something;
}
else
{
    //Then go back to a switch statement inside the else for the remaining cases if you really need to
}

문자열 케이스의 수에 관계없이이 스케일이 좋습니다.

1
Maxter

.NET 4.6.2를 사용하여 대화에 추가하기 위해 다음을 수행 할 수도있었습니다. 나는 코드를 테스트했고 그것은 나를 위해 일했다.

아래와 같이 여러 개의 "OR"문을 수행 할 수도 있습니다.

            switch (value)
            {
                case string a when a.Contains("text1"):
                    // Do Something
                    break;
                case string b when b.Contains("text3") || b.Contains("text4") || b.Contains("text5"):
                    // Do Something else
                    break;
                default:
                    // Or do this by default
                    break;
            }

배열의 값과 일치하는지 확인할 수도 있습니다.

            string[] statuses = { "text3", "text4", "text5"};

            switch (value)
            {
                case string a when a.Contains("text1"):
                    // Do Something
                    break;
                case string b when statuses.Contains(value):                        
                    // Do Something else
                    break;
                default:
                    // Or do this by default
                    break;
            }
0
JeffS