c# - 코딩 - csharp coding standards pdf




예방 적 대 반응 C#프로그래밍 (6)

나는 항상 오류가 없을 것이라는 확신이 들지 않으면 조치를 취하지 않음으로써 예외 조건을 예방하는 측면에서 잘못을 저지른 사람이었습니다. 나는 C로 프로그램하는 것을 배웠고 이것은 정말로 일을하는 유일한 길이었다.

C #으로 작업하기 저는 자주 반응적인 프로그래밍을 봅니다. 뭔가를 시도하고 예외를 처리하려고합니다. 나에게 이것은 예외를 컨트롤 문으로 사용하는 것과 같다. 처음 몇 번이나 나는 이것을 나쁜 행동으로 일축했다. 그러나 지난 몇 개월 동안 나는 그것을 온통 보았고 단지 의문을 제기해야합니다 - 이것이 수용 되었습니까 / 아니면 효율적입니까 아니면 전염병입니까?

업데이트 : 약간의 설명을 위해 예외 처리의 대부분은

try
{
    //open file
}
catch
{
    //message box for file not found
}

또는 더 나쁜

try
{
    //open xml
    //modify xml (100+ lines of code)
}
catch
{
    //message for 'unspecified error'
}

나는 예외 처리가 (데이터베이스 연결과 같은) 사용하기에 매우 좋은 때가 있다는 것을 이해하지만 더 전통적인 '제어'대신에 예외의 사용을 언급하고있다. 나는이 프로그래밍 스타일이 복구 방법 대신에 버팀목으로 예외를 사용하고 이것이 C # 세계에서 기대하는 법을 배워야한다는 것을 알고 싶었 기 때문에이 질문을 던졌습니다.


C ++에서 try 블록을 입력하는 것은 CPU 사이클과 관련하여 비용이 많이 드는 작업이므로 이러한 이유로 사용을 최소화해야합니다. C #의 경우 try 블록을 입력하는 것이 저렴하므로 다른 방법으로 사용할 수 있습니다.

지금; C #에서 예외를 잡는 것은 비용이 많이 들며 예외적 인 경우에도 사용되어야하며 일반 프로그램 논리에는 사용되지 않아야합니다.


C / C ++는 반응적일 수 있습니다. NULL 체크가 뒤따라 오기까지 시도 된 것을 몇 번이나 보았습니까? 예외의 장점은 NULL 또는 False 리턴보다 많은 정보를 제공 할 수 있다는 것입니다.

예외를 지원하는 언어로 예외를 throw하는 대부분의 작업은 작업을 성공적으로 수행하기 전에 "테스트"할 방법이 없습니다.

이제 런타임 예외는 모두 서로 다른 것입니다. 이는 일반적으로 유효하지 않은 데이터 또는 데이터 오용 (0으로 나눈 값)으로 인해 발생합니다. 이런 종류의 예외는 내 생각에 절대로 그걸 다루는 방법으로 잡아서는 안됩니다.


늘 그렇듯이 대답은 "의존적"이지만 일반적으로 "실패 빠른"철학에 가입합니다.

try / finally (sans catch)를 사용하는 것을 선호합니다. 실제로 코드의 특정 블록에서 예외를 복구하는 데 유용하지는 않습니다. 가능한 모든 예외를 포착하는 것은 가치가 없습니다. 일반적으로 자동으로 실패하는 것보다 빠른 실패가 바람직합니다.

반면에 특정 예외에서 복구하는 방법을 알고 있다면 그렇습니다.

파일 전송 라이브러리가 있다고 가정 해보십시오. 타임 아웃이나 네트워크 장해로 인해 전송이 중단되면 아마 예외가 발생할 것이다. 그건 합리적입니다. 도서관이 조용히 실패하면 당신은 짜증이납니다. 반환 코드를 확인하는 것이 오류가 발생하기 쉽고 반드시 읽을 필요는 없습니다. 그러나 아마도 서버에 파일을 전송하기위한 비즈니스 규칙이 있는데,이를 포기하고 사용자 개입을 요구하기 전에 파일 전송을 적어도 3 번 시도해야합니다. 이 경우 비즈니스 로직이 예외를 처리하고 복구를 시도한 다음 자동 솔루션이 실패 할 때 (사용자에게 경고하거나 나중에 시도 일정을 예약하는 등) 수행해야 할 작업을 수행해야합니다.

이 작업을 수행하는 코드를 찾은 경우

try
{
    // do something that could throw
    // ...
}
catch {} //swallow the exception

또는:

catch { return null; }

그것은 아마도 부러 졌을 것입니다 . 물론, 때때로 호출하는 코드는 여러분이 정말로 신경 쓰지 않는 예외를 던질 수 있습니다. 그러나 저는 사람들이 예외적으로 예외를 "처리"할 필요가 없다는 것을 자주 보았습니다. 연습은 디버그하기가 더 어렵게 만듭니다.

어떤 사람들은 예외적으로 책임의 사슬을 계단식으로 쌓아 두는 것이 좋다고 생각합니다. 왜냐하면 당신이 상류에있는 누군가가 "기적적으로"무엇을해야하는지 알기를 "바라고"있기 때문입니다. 그 사람들은 잘못입니다. 업스트림 코드는 대개 무엇을 해야할지 알 있는 유일한 장소입니다.

때때로, 나는 좀 더 적절한 예외를 잡으려고 할 것이다. 그러나 가능한 경우 보호 절이 더 좋습니다. e, g. if (argument==null) throw new ArgumentNullException(); 무엇이 잘못되었는지 명확하기 때문에 NullReferenceException이 호출 스택을 전파하도록 허용하는 것보다 낫습니다.

어떤 상황은 "절대로 일어나지 않아야"또는 "일어날 수 있는지 몰랐습니다"(예를 들어, jboss 로깅 참조) 기록되어야하지만 적어도 일부 경우에는 응용 프로그램을 종료하기 전에 삼킬 수 있습니다.

ETA : 특정 예외를 취한 다음 일반적이고 모호한 오류 메시지를 표시하는 것은 아마도 손상되었을 것입니다. 위의 두 번째 예를 들어, 나에게 나쁜 소리. 첫 번째로, "파일을 찾을 수 없습니다"는 경우, 그 조건을 다른 곳에서 다루는 더 좋은 방법이 없다면, 더 합리적 일 수 있습니다 (실제로 특정 예외를 잡은 경우 "모든 것"이 아니라). 모달 메시지 상자는 대개 나에게 나쁜 "상호 작용 디자인 냄새"이지만, 대부분 요점 옆에 있습니다.


단서는 "예외"라는 용어에 있습니다.

인수가 널 (null) 인 것이 유효한 비즈니스 조건 인 경우 정의에 따라 널 (null) 인수는 예외가 아니며 사용하기 전에 테스트 해야 합니다. 이러한 비즈니스 조건에서 예외를 사용하여 프로그램 논리를 제어하면 코딩이 엉성 해지며 가해자는 회개 할 때까지 젖은 방목장에서 반복적으로 때려야합니다.

그러나 성능을 제쳐두고,이 예제에서 널 인수를 항상 맹목적으로 테스트하는 것은 예외가 throw 될 때 항상 예외를 트래핑하는 것보다 낫지 않습니다.

인수가 null가능성이없는 경우 null 을 테스트 하지 않아야합니다. 처리되지 않은 예외가 트래핑되고 저장되며 지원 팀에 전자 메일로 보내지 는 사용자의 숨겨진 예외가있는 경우를 제외하고는 null에 대한 테스트를 수행 해서는 안됩니다 . 사과를 통해 적절한 메시지가 표시되어야합니다.

한 번 생각할 수있는 모든 예외가 처리 된 앱을 디버깅해야했지만 디버깅은 문자 그대로 불가능했습니다. 데이터베이스와 함께 개발 환경에서 dev envt로 가져와야했으며, 모든 핸들러가 찢어졌습니다. 그 후에 그것은 사소했습니다.


어떤 경우에는 사후 대응이 불가피한 경우가 있습니다. 점검 및 작동이 항상 작동하는 것은 아닙니다.

디스크의 파일 액세스 : 디스크가 작동합니까? 파일이 존재합니까? 파일에 대한 읽기 권한을 얻을 수 있습니까?

데이터베이스 액세스 : 서버가 연결을 허용합니까? 내 자격증은 좋은가요? 데이터베이스 개체가 존재합니까? 이름이 지정된 / 열이 적절하게 입력 되었습니까?

이러한 모든 사항은 수표와 운영간에 변경 될 수 있습니다.


예외 전략에 대한 전반적인 논의없이 예외의 최선의 사용에 관해 논의하는 것은 어렵습니다. 예를 들어 전략은 다음 중 하나 일 수 있습니다.

  • 모든 예외를 가능한 한 실패 시점에 가깝게 처리하십시오.
  • 예외를 기록한 다음 호출자에게 다시 던지십시오.
  • 사전 예외 상태로 롤백하고 계속 시도하십시오.
  • 예외를 적절한 오류 메시지로 변환하고 사용자에게 표시합니다.

예외 처리는 종종 동일한 프로젝트에서 작업하는 여러 개발자가 동일한 전략을 가지고 있지 않거나 심지어 더 나쁜 경우에도 존재한다는 것을 알지 못하기 때문에 복잡해질 수 있습니다. 따라서 팀의 모든 구성원이 전략이 무엇인지 알고 이해하는 것이 중요합니다.

예외 처리 및 전략에 대한 좋은 출발점은 Ned Batchelder의 블로그 게시물 인 열대 우림의 예외를 참조하십시오.





coding-style