2009-07-29 6 views
2

은 다음과 델파이 파스칼 코드를 고려 : 내가 TComponent의 함께 할 수있는 몇 가지 다형성 물건이 거기에 아마 알고DELPHI : 루프 또는 케이스 외부에서 "break"를 사용하는 방법은 무엇입니까?

var 
    tc: TComponent 
begin 
{ do something to get tc } 
repeat 
    if(tc is TDBEdit)then begin 
    if(check_something_about_edit(tc))then break; 
    do_something_else_edit(tc); 
    break; 
    end else if(tc is TBMemo) then begin 
    if(check_something_about_memo(tc))then break; 
    do_something_else_memo(tc); 
    break; 
    end; 
    raise exception.create('invalid component type'); 
until(true); {single iteration look required to use break } 

을하지만 내 질문이 아니다. 나는 하나의 반복 repeat-until 문을 없애는 방법이 있는지 궁금 하네. 그것 없이는 처리 블록 어디에서나 break 문을 사용할 수 없으며 언제든지 처리를 중단해야합니다.

+1

실제로, 여러분이 할 수있는 "polymorphic stuff"가있을 것입니다. 두 컴포넌트 유형 모두 'TCustomEdit'에서 파생됩니다. 'tc'의 선언을 그 것으로 변경하십시오. –

+2

+1. 게시 한 코드가 잔인한 것이지만 개선 방법을 묻는 것은 정확합니다. 한 번 이상 실행하지 않는 루프가있을 때마다 잘못된 결과가 발생합니다. –

답변

4

함수에 팩하고 exit를 사용하여 뒤로 이동하십시오. repeat 문을 따르는 코드가 더 있으면 다음과 같이 로컬 함수/프로 시저를 사용하십시오.

procedure ... 
    procedure testsomething(tc: TComponent); 
    begin 
    if(tc is TDBEdit)then begin 
     if(check_something_about_edit(tc))then exit; 
     do_something_else_edit(tc); 
     exit; 
    end else if(tc is TBMemo) then begin 
     if(check_something_about_memo(tc))then exit; 
     do_something_else_memo(tc); 
     exit; 
    end; 
    raise exception.create('invalid component type'); 
    end; 

var 
    tc: TComponent; 
begin 
{ do something to get tc } 
    try 
    TestSomething(tc); 
    { do something more } 
    except 
    ... 
    end; 
end; 
+0

이 특별한 경우에 if-else 솔루션이 더 정확한 반면이 솔루션은 실제 사례에 더 적용 가능합니다. 많은 코드를 움직여야하지만 괜찮습니다. 나는 일을 올바르게하는 것을 선호한다. –

4

실제로 수행하는 작업은 goto로 break를 사용하는 것입니다. 기능을 범위로 사용하라는 랄프의 제안은 좋은 것입니다. 하지만 그렇지 않다면 정직하게 "고토 완성"을 할 수도 있습니다. 반복을 잃으면 실제로 더 읽기 쉽습니다.

+0

hmmm, goto가 실제로는/less/evil 인 경우입니다. 이상한 날들 ... –

+0

글쎄, 당신은 휴식의 아주 나쁜 사용을 생각해 냈습니다. 그리고 어쨌든 break/continue는 구조화 된 goto입니다. –

14

갈 수있는 또 다른 쉬운 방법이 있습니다 :

if(tc is TDBEdit)then begin 
    if not (check_something_about_edit(tc)) then 
    do_something_else_edit(tc); 
end else if(tc is TBMemo) then begin 
    if not (check_something_about_memo(tc)) then 
    do_something_else_memo(tc); 
end else 
    raise exception.create('invalid component type'); 
end; 
+0

내가 처음 게시 한 것보다 훨씬 좋은 대안이라고 생각합니다. –

+0

도 마찬가지지만 코드를 통과하는 데 시간이 걸렸습니다.) –

+0

다른 하나를 남겨 둡니다. 비슷한 설정에서 유용 할 수 있습니다. –

1

왜 종료보다는 휴식을 사용 하시겠습니까? 델파이의 중단은 중괄호 언어의 "중단"과 동일하지 않습니다.

var 
    tc: TComponent 
begin 
    { do something to get tc } 
    if (tc is TDBEdit) then 
    begin 
    if not (check_something_about_edit(tc)) then 
     do_something_else_edit(tc); 
    Exit; 
    end; 
    if (tc is TBMemo) then 
    begin 
    if not (check_something_about_memo(tc)) then 
     do_something_else_memo(tc); 
    Exit; 
    end; 
    raise exception.create('invalid component type'); 
end; 

레이아웃에 대한 요점. 공백을 너무 많이 줄이려고 시도하지 않았다면 더 이상 그렇지 않을 수도 있습니다. 이전 의견에서 말했던 것처럼 "내 모든 if-else가 올바르게 정렬되어 있는지 확인하는 데 한 시간 더"걸릴 수 있습니다.

이후에 실행할 코드가있는 경우 Ralph의 로컬 프로 시저 제안을 사용하거나 try..finally로 랩핑하십시오. finally의 코드는 여전히 실행됩니다.