2010-07-06 6 views
16

가끔 변수를 잘못 사용하는 것을 피하기 위해 코드 블록을 분리하기 위해 중괄호를 사용하기도합니다. 예를 들어, 동일한 메소드에 여러 개의 SqlCommand을 넣으면 자주 코드 블록을 복사하여 붙이며 이름을 혼합하고 두 번 명령을 실행합니다. 잘못된 위치에 잘못된 SqlCommand을 사용하면 오류가 발생하기 때문에 중괄호를 추가하면 이러한 상황을 피할 수 있습니다. 다음 그림이 있습니다.가변 범위 용도로 중괄호를 사용하는 것은 잘못 되었습니까?

Collection<string> existingCategories = new Collection<string>(); 

// Here a beginning of a block 
{ 
    SqlCommand getCategories = new SqlCommand("select Title from Movie.Category where SourceId = @sourceId", sqlConnection, sqlTransaction); 
    getCategories.Parameters.AddWithValue("@sourceId", sourceId); 
    using (SqlDataReader categoriesReader = getCategories.ExecuteReader(System.Data.CommandBehavior.SingleResult)) 
    { 
     while (categoriesReader.Read()) 
     { 
      existingCategories.Add(categoriesReader["Title"].ToString()); 
     } 
    } 
} 

if (!existingCategories.Contains(newCategory)) 
{ 
    SqlCommand addCategory = new SqlCommand("insert into Movie.Category (SourceId, Title) values (@sourceId, @title)", sqlConnection, sqlTransaction); 

    // Now try to make a mistake and write/copy-paste getCategories instead of addCategory. It will not compile. 
    addCategory.Parameters.AddWithValue("@sourceId", sourceId); 
    addCategory.Parameters.AddWithValue("@title", newCategory); 
    addCategory.ExecuteNonQuery(); 
} 

이제 StyleCop은 블록이 빈 줄을 따라갈 때마다 경고를 표시합니다. 반면에 빈 줄을 두지 않으면 코드를 이해하기가 훨씬 어려워집니다. 다만 변수 범위 목적 코드의 블록을 만들 중괄호 사용에 잘못 뭔가

// Something like: 
Collection<string> existingCategories = new Collection<string>(); 
{ 
    // Code here 
} 

// can be understood as (is it easy to notice that semicolon is missing?): 
Collection<string> existingCategories = new Collection<string>() 
{ 
    // Code here 
} 

그래서,

  1. 있습니까?

  2. 괜찮 으면 StyleCop 규칙을 위반하지 않고 가독성을 높이려면 어떻게해야합니까?

+3

이러한 것을 익명 블록이라고합니다. 관련 항목 : http://stackoverflow.com/questions/85282/what-is-the-value-of-an-anonymous-unattached-block-in-c 및 http://stackoverflow.com/questions/500006/what- 익명 -blocks-in-c-style-languages ​​언어 –

답변

5

나는 범위를 구분하기 위해 중괄호를 사용하는 것이 잘못되었다고 생각하지 않습니다. 때때로 유용 할 수 있습니다.사례 : 요점 사례 - 나는 코드 라이브러리의 시간 섹션에 Profile 개체를 사용한 한 번 프로파일 링 라이브러리를 발견했습니다. 이것들은 창조에서 파괴까지의 시간을 측정함으로써 이루어졌고, 따라서 스택에서 생성 된 다음 범위를 벗어 났을 때 파괴되어 그 특정 범위에서 소비 된 시간을 측정함으로써 가장 잘 작동했습니다. 본질적으로 자체 범위가없는 무언가를 시간에두고 싶다면 범위를 정의하기 위해 여분의 중괄호를 추가하는 것이 아마도 최선의 방법 일 것입니다.

가독성에 대해서는 StyleCop이 좋아하지 않는 이유를 이해할 수 있지만 C/C++/Java/C# /에 대한 경험이있는 사람이라면 중괄호 쌍이 범위를 정의한다는 것을 알고 있어야합니다. 그것이 당신이하려고하는 것이 분명합니다.

12

베어 브레이스 블록 대신 using 문을 사용하십시오.

이렇게하면 경고를 피할 수 있으며 리소스 측면에서 코드를보다 효율적으로 만들 수 있습니다.

큰 관점에서 볼 때이 방법을 더 작은 방법으로 나누는 것을 고려해야합니다. SqlCommand 다음에 다른 하나를 사용하는 것은 대개 하나의 메소드를 호출하고 다른 메소드를 호출하여 더 잘 수행됩니다. 그런 다음 각 메서드는 자신의 로컬 SqlCommand을 사용합니다.

+8

using()이 IDisposable을 필요로한다고 생각합니다. –

+0

이것은 'SqlCommand'가'IDisposable'을 구현했기 때문에이 특정 시나리오에 적용되지만 일반적인 경우는 해결되지 않습니다. –

+0

추한 데다 대신 do {...} while (false);를 사용할 수 없습니다. 그렇다면 경고를 해제하는 것이 더 나은 해결책 일 것입니다. –

18

그 자체는이며 코드를 차단하고 있지만, 왜 그런지 고려해야합니다.

코드를 복사하여 붙여 넣는 경우 비슷하지만 다른 코드 블록을 반복적으로 실행하는 대신 반복적으로 호출하는 코드와 리팩터링 기능을 사용해야하는 상황이 발생할 수 있습니다.

+4

나는 동의한다. 기술적으로 잘못된 것은 없으며, 문체에 대한 불만 사항이며 잠재적으로 더 작고 관리하기 쉬운 부분으로 분리되어야하는 긴 기능에 대한 경고 표시 일 수도있다. –

+0

"코드를 리 팩토링해야하는 상황에 처한 것 같습니다."큰 코드 블록의 복사/붙여 넣기가 아닙니다. 두 변수의 이름이 비슷한 경우 ('sqlGetProductFromTable' 대'sqlAddProductToTable') Intellisense를 사용할 때 동일한 문제가 발생합니다. 변수 이름을 잘못 입력하는 것은 쉽습니다. 컴파일러의 경우 코드가 완벽하게 정확하기 때문에 실행되지만 예상치 못한 결과가 발생합니다. –

+0

@MainMa : 블록을 재사용하는 것이 리팩토링하는 유일한 이유는 아닙니다. 방금 거대한 방법은 혼자서 작은 조각으로 나누는 좋은 이유가 될 수 있습니다. –

4

이러한 블록이 좋은 생각이라고 생각합니다. 자주 사용하고 있습니다. 메서드로 추출하기에 너무 작은 코드 블록을 분리해야하거나 메서드가 몇 가지 코드 블록으로 이루어진 경우 처럼 보이지만 같은 논리는 아닙니다. 이름 충돌없이 변수에 동일한 이름을 부여 할 수 있으므로 메서드 본문을 더 쉽게 읽을 수 있습니다.

그건 그렇고, 내 생각에 StyleCop은 기본 규칙이 더 많은 규칙으로 설정되어있어 편의가 논쟁의 여지가 있습니다.

3

나는이 코드를 작업 한 후에도 범위를 사용하여 약간의 차이가있을 것이라고 말하고 싶습니다. 그것의 afaik, 일반적인 연습.

나는이 일을 수행 할 때 냄새라고 생각합니다. 더 나은 방법은 각 범위를 완전히 설명하는 이름과 문서로 자체 메서드로 분리하는 것입니다.

0

변수의 범위를 제한하기 위해 중괄호를 사용해야하는 경우 메서드가 너무 길어질 수 있습니다. 다른 사람들이 이미 쓴 것을 강조하고 싶었습니다.