문제

내가 유지하고있는 일부 delphi 7 코드에서는 다음과 같은 많은 사례를 발견했습니다.

with ADOQuery1 do begin
  // .. fill out sql.text, etc
  try
    execSQL;
  except
    raise;
  end;
end;

이 시도 블록은 아무것도하지 않기 때문에 제거 될 수있는 것 같습니다. 그러나 나는 미묘한 부작용에 대해 조심한다 ..

누구 든지이 블록이 실제로 그 없이는 일어나지 않을 일을 할 수있는 사례를 생각할 수 있습니까?

도움이 되었습니까?

해결책

이러한 맥락에서, 인상 작업은 영향을 미치지 않으며 예외 블록이 방금 잡힌 예외를 다시 제출하기 때문에 제거해야합니다. 적절한 오류 처리를 사용할 수없는 경우 인상은 일반적으로 블록 끝으로 컨트롤을 전송하는 데 사용됩니다. 다음에서는 사용자 정의 예외를 처리하지만 다른 예외는 다른 곳에서 처리되어야합니다.

try
  someOperation;
except
  on e: ECustomException do
    SomeCustomHandelr;
  else
     begin
       // the raise is only useful to rethrow the exception to an encompasing 
       // handler.  In this case after I have called my logger code. as Rob
       // mentioned this can be omitted if you arent handling anything because
       // the compiler will simply jump you to the next block if there is no
       // else.
       LogUnexpectedException('some operation failed',e);
       raise;
     end;
end;

예외를 먹거나 숨기는 부작용이있는 "인상"이없는 비슷한 모양의 형태가 있음을주의하십시오. 희망적으로 경쟁 업체와의 위치로 넘어간 매우 부도덕 한 개발자들의 실습.

with ADOQuery1 do begin  
  // .. fill out sql.text, etc  
  try    
    execSQL; 
  except
    // no handler so this just eats any "errors"    
  end;

다른 팁

위의 코드 스 니펫에서 제외 코드를 제거하면 차이가 없습니다. 당신은 할 수 있습니다 (그리고 나는 당신을 믿습니다 ~해야 한다 가독성을 줄이기 때문에) 제거하십시오.

좋아요, 정말 두 가지 질문이 있습니다.

먼저, 그것은 ~이다 의미있는 : ExecSQL이 예외를 던지면 시도 블록에 의해 잡히고 제외로 전달됩니다. 그런 다음 다음 상위 블록으로의 인상으로 전달됩니다.

둘째, 그것은입니다 유용한? 아마 그렇지 않을 것입니다. 거의 확실히 세 가지 중 하나의 결과입니다.

  1. 뾰족한 머리카락을 가진 사람은 코딩 표준을 썼습니다. "예외를 던질 수있는 모든 작업은 시도 블록에 있어야합니다."
  2. 누군가가 돌아와서 execSQL 더 의미있는 다른 예외에 대한 진술.
  3. 새로운 사람은 자신이 쓴 것이 자궁 환경이 예외에 대해 걱정하는 것에 동형이라는 것을 알지 못했기 때문에 ~ 해야 하다 전달.

조금 빨리 대답했을 수도 있습니다. 결국 참조하십시오 ...
마찬가지로 응용 프로그램에는 쓸모가 없습니다..
기간!

이제 "왜"쪽에. 다른 장소에/있을 경우//있을 경우 예외 처리를 표준화하는 것일 수 있습니다.

  try
    execSQL;
  except
    // Log Exception..
    on E: Exception do
    begin
      LogTrace(Format('%s: Exception Message[%s]',[methodname, E.Message]));
      raise;
    end;
  end;

또는 정리 코드 :

  try
    execSQL;
  except
    //some FreeAndNil..
    raise;
  end;

업데이트: 내가 그와 마찬가지로 약간의 용도를 볼 수있는 사례가있을 것입니다 ...
...에 중단 점을 넣을 수 있으려면 raise 라인, 해당 코드 블록의 맥락에서 무슨 일이 일어나고 있는지 확인할 수있는 기회를 얻으십시오.

이 코드는 원래 프로그래머가 'Raine'에 중단 점을 놓고 가능한 원인에 대한 예외를 더 가깝게 보는 것 외에는 아무것도하지 않습니다. 그런 의미에서 완벽하게 합리적인 디버깅 기술입니다.

실제로, 나는 이것을 François의 답변에 댓글로 게시해야하지만, 그곳에 형식화 된 코드를 삽입 할 수 있다는 것을 모르겠습니다. 그래서 나는 이것을 답으로 게시하고 있습니다.

2mghie :

두 번째는 완전히 일체형이며, 하나는 마침내 사용될 것입니다.

아니요, "마침내"는 항상 개체를 정리합니다. "제외" - 예외 만. 개체를 생성, 채우고 반환하는 기능의 경우를 고려하십시오.

function CreateObj: TSomeObj;
begin
  Result := TSomeObj.Create;
  try
    ... // do something with Result: load data, fill props, etc.
  except
    FreeAndNil(Result); // oops: bad things happened. Free object to avoid leak.
    raise;
  end;
end;

당신이 "마지막으로"거기에 놓으면 - 기능은 항상 nil을 반환합니다. "시도"블록을 생략하면 "..."에서 예외가 발생하면 리소스 누출이 발생합니다.

물론, 당신은 "마침내"를 사용하고 offobj를 제외하고 확인할 수는 있지만 ... 그것은 못생긴 일이 아니십니까?

제목에는 상당히 넓은 질문이 포함되어 있으며 설명은보다 구체적인 예를 제공합니다. 따라서 예제에서 진행되는 방법으로 질문에 대한 답변은 의심 할 여지없이 이미 언급 된 내용에 유용한 것을 추가 할 수 있습니다.

하지만, 아마도 Blorgbeard는 실제로 그것이 있는지 알고 싶어합니다 조금도 의미가 있습니다 try ... except raise; end. 델파이 7에서, 내가 올바르게 회상하면 Exit 트리거 할 것입니다 finally a의 일부 try-finally 차단 (예외가 예외 인 것처럼). 누군가는 그러한 행동이 자신의 임무에 부적절하다고 생각할 수 있으며, 해당 구성을 사용하는 것은 상당히 해결책입니다.

단 하나만 사용하는 것이 여전히 이상합니다. raise; 거기에, 그러나 우리는 이야기 했어야했다 유용성 보다는 의미가 있습니다, Charlie가 깔끔하게 관찰 한 것처럼.

이 코드는 블록을 제외 하고이 시도없이 모든 준비가 될 예외를 다시 제외하는 것 외에는 아무것도하지 않습니다. 안전하게 제거 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top